【问题标题】:Getting a Colour Scheme from an Image从图像中获取配色方案
【发布时间】:2010-01-11 15:34:16
【问题描述】:

我想开发一个像featured here 这样的基本工具。我将截取一些网页的屏幕截图,然后我希望从中选出最流行的前五种颜色,然后以某种方式决定这些颜色是否合适。

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

这里有人可以就我如何创建一个程序来执行与上述程序类似的事情提供建议,该程序将接收图像并选择图像中使用的前五种颜色?

【问题讨论】:

  • serhio 提出了一个关于使用缩略图的出色观点。这样,评估图像所需的时间将迅速缩短。 +1

标签: c# color-scheme


【解决方案1】:

嗯.. 使用缩略图(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

【讨论】:

  • 那是天才!我从来没有想过这样做。我还不能测试代码,因为我的笔记本电脑坏了,但无论如何我都会接受答案。非常感谢!
  • 嗯,那个图片所在的博客是不是挂了?图像似乎不再存在。如果你还有的话,你应该考虑用编辑器中的图片按钮上传它。
  • 不会因为高对比度高光没有在很多图像中使用而去掉吗?我想要保留这些细节的东西,而不是过滤掉过于相似的颜色。
【解决方案2】:

如你所说,最简单的方法是:

  • 读取每个像素并将它们存储在 一个集合。

  • 使用的前五种颜色是 出现次数最多的值。

这就是我之前第一次尝试这样的事情的方式。

为了进一步开展这项工作,您可以采用颜色范围,因此使用 RGB 值 (Red, Green, Blue) 将颜色分配给某个颜色的近似值。

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

对其他像素重复。

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

0.7, 0.0, 0.0

您可以通过添加/乘以一个值来扩展它。但是,请将值保持在 0 到 1 的范围内。至于缩放值应该是多少,实验性的。它越高,颜色会变得越暗/越亮。

【讨论】:

  • 我应该补充一点,当使用 bmp 图像时,读取单个像素并对其进行处理是相当简单的,因此使用您在本文中获得的一些建议将原型放在一起应该是相当可行的.
  • @Dockers,平台是 C#/.NET。因此,所有常见文件都有一个 API,即 GetPixel/SetPixel 和 X/Y。
  • GetPixel/SetPixel 很慢。我更喜欢只遍历支持数据数组。
【解决方案3】:

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2012-07-09
  • 1970-01-01
  • 2016-10-27
  • 2013-07-21
  • 1970-01-01
  • 2019-07-27
  • 2012-08-16
  • 1970-01-01
相关资源
最近更新 更多