从图像中获取颜色方案

时间:2010-01-11 15:34:16

标签: c# color-scheme

我想开发一个像featured here这样的基本工具。我将截取一些网页的截图,从那里我想采取前五种最流行的颜色,并从那里以某种方式决定颜色是否是一个很好的匹配。

我想用C#编写这个工具,经过一些研究后我发现了lockbits。我的第一个想法是拍摄一张图像,然后获得每个像素的颜色,但我不确定这是否会给我我想要的结果以及如何制作六种最流行的颜色列表。

这里的任何人都可以提供关于如何创建程序以执行类似于上述程序的建议,该程序将采用图像并选择图像中使用的前五种颜色吗?

3 个答案:

答案 0 :(得分:16)

嗯..使用缩略图(16x16,32x32等)并从中选择颜色

更新代码:

    private void button1_Click(object sender, EventArgs e)
    {
        int thumbSize = 32;
        Dictionary<Color, int> colors = new Dictionary<Color, int>();

        Bitmap thumbBmp = 
            new Bitmap(pictureBox1.BackgroundImage.GetThumbnailImage(
                thumbSize, thumbSize, ThumbnailCallback, IntPtr.Zero));

        //just for test
        pictureBox2.Image = thumbBmp;            

        for (int i = 0; i < thumbSize; i++)
        {
            for (int j = 0; j < thumbSize; j++)
            {
                Color col = thumbBmp.GetPixel(i, j);
                if (colors.ContainsKey(col))
                    colors[col]++;
                else
                    colors.Add(col, 1);
            }                
        }

        List<KeyValuePair<Color, int>> keyValueList = 
            new List<KeyValuePair<Color, int>>(colors);

        keyValueList.Sort(
            delegate(KeyValuePair<Color, int> firstPair,
            KeyValuePair<Color, int> nextPair)
            {
                return nextPair.Value.CompareTo(firstPair.Value);
            });

        string top10Colors = "";
        for (int i = 0; i < 10; i++)
        {
            top10Colors += string.Format("\n {0}. {1} > {2}",
                i, keyValueList[i].Key.ToString(), keyValueList[i].Value);
            flowLayoutPanel1.Controls[i].BackColor = keyValueList[i].Key;
        }
        MessageBox.Show("Top 10 Colors: " + top10Colors);
    }

    public bool ThumbnailCallback() { return false; }

alt text http://lh3.ggpht.com/_1TPOP7DzY1E/S0uZ6GGD4oI/AAAAAAAAC5k/3Psp1cOCELY/s800/colors.png

答案 1 :(得分:2)

最简单的方法,就像你说的那样:

  • 读入每个像素并存储它们 一个集合。

  • 使用的前五种颜色是 发生最多的价值。

这就是我以前第一次尝试这样的事情。

为了进一步完成这项工作,您可以使用颜色范围,因此使用RGB值(Red, Green, Blue)可以为某种颜色近似值指定颜色。

例如,假设使用相同的图像,浅蓝色值将被存储在一起,然后可以获取这些值的平均值,以在场景中给出最常见(但平均)的淡蓝色。

重复其他像素。

至于缩放 - 示例网站使用暗淡/明亮的值。可以使用简单的比例值。考虑RGB中红色:

0.7, 0.0, 0.0

您可以通过添加/乘以值来缩放此值。但是,将值保持在0到1的限制范围内。至于缩放值应该是什么,实验。它越高,颜色变得越淡/越亮。

答案 2 :(得分:2)

This是如何创建直方图(或其他单词中的频率表)的示例,您可以在其中查看有关如何处理图像的详细信息。

但我的主要建议是不要使用RGB(除非您正在查看的网站主要是纯色),而是使用HSB。 “H”(色调)组件将为您提供更好的颜色指示,无论它们有多亮或多暗。