如何获得图像中的多数颜色?

我想在.NET中检索背景图像中的大部分颜色。 可能吗?

您可以遍历图像中的所有像素,并使用getPixel方法确定RGB值。 然后可以有一个存储ARGB值和一个计数的字典。 然后,您可以看到图像中哪个ARGB值最多。

var list = new Dictionary<int, int>(); Bitmap myImage = (Bitmap)Bitmap.FromFile("C:/test.jpeg"); for (int x = 0; x < myImage.Width; x++) { for (int y = 0; y < myImage.Height; y++) { int rgb = myImage.GetPixel(x, y).ToArgb(); if (!list.ContainsKey(rgb)) list.Add(rgb, 1); else list[rgb]++; } } 

正如所指出的那样,对同类色彩没有同情。 如果你想要一个更“一般”的多数颜色,你可以有一个相似的门槛。 例如而不是:

 if (!list.ContainsKey(rgb)) list.Add(rgb, 1); else list[rgb]++; 

你可以这样做:

 var added = false; for (int i = 0; i < 10; i++) { if (list.ContainsKey(rgb+i)) { list[rgb+i]++; added = true; break; } if (list.ContainsKey(rgb-i)) { list[rgb-i]++; added = true; break; } } if(!added) list.Add(rgb, 1); 

无论你需要什么,你都可以达到10的门槛。

你也可以发现堆栈溢出算法的挑战很有用:

算法挑战:从图像生成颜色方案

还要考虑创建图像的直方图 – 并将最高的颜色作为“多数颜色”: http : //www.phpclasses.org/browse/file/15953.html

这将返回图像的平均颜色。

 static Color AverageColor(string fileName) { using (var bmp = new Bitmap(fileName)) { int width = bmp.Width; int height = bmp.Height; int red = 0; int green = 0; int blue = 0; int alpha = 0; for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { var pixel = bmp.GetPixel(x, y); red += pixel.R; green += pixel.G; blue += pixel.B; alpha += pixel.A; } Func<int, int> avg = c => c / (width * height); red = avg(red); green = avg(green); blue = avg(blue); alpha = avg(alpha); var color = Color.FromArgb(alpha, red, green, blue); return color; } } 

这将使用不安全的指针访问返回图像的平均颜色。 注意:代码只适用于24bppRgb,可以适用于其他像素格式。

  unsafe static Color GetColor(string filename) { using (var image = (Bitmap)Bitmap.FromFile(filename)) { if (image.PixelFormat != PixelFormat.Format24bppRgb) throw new NotSupportedException(String.Format("Unsupported pixel format: {0}", image.PixelFormat)); var pixelSize = 3; var bounds = new Rectangle(0, 0, image.Width, image.Height); var data = image.LockBits(bounds, ImageLockMode.ReadOnly, image.PixelFormat); long r = 0; long g = 0; long b = 0; for (int y = 0; y < data.Height; ++y) { byte* row = (byte*)data.Scan0 + (y * data.Stride); for (int x = 0; x < data.Width; ++x) { var pos = x * pixelSize; b += row[pos]; g += row[pos + 1]; r += row[pos + 2]; } } r = r / (data.Width * data.Height); g = g / (data.Width * data.Height); b = b / (data.Width * data.Height); image.UnlockBits(data); return Color.FromArgb((int)r, (int)g, (int)b); } } 

要点: http : //gist.github.com/349210

假设您使用RGB (相对于CMYK )表征每个像素的颜色,则可以构建一个3d数组(每个R,G和B都有一个维度)。 然后决定你想要在每个维度上的箱子数量 – 箱子越多,你在类似的色调之间的差异就越大。

一旦完成,只需迭代通过图像的位图表示就可以将#像素落入您的3D数组中的每个单元格中。 总和最高的单元格将是主要的颜色。

您可能想要使您的算法可以轻松配置为每个维度中的#个区域,以便您可以调整区分相似颜色的程度。

 image = new Bitmap("C:\\test.bmp", true); int x, y; // Loop through the images pixels to product 3d histogram for(x=0; x<image.Width; x++) { for(y=0; y<image.Height; y++) { Color pixelColor = image.GetPixel(x, y); // Increment color count in appropriate cell of your 3d histogram here ... } }