jpg 画像ファイルの 3 ~ 4 色の主要な色を検出できるようにしたいと考えています。
以下のサンプル画像とサンプルコード:
- 赤、黒、白
- 白、緑、ピンク
- 青、黄、黒
以下を取得するためにいくつかのコードを変更しましたが、色のグループ化にはまだ問題があります。
public static int RoundColorToGroup(int i)
{
int r = ((int)Math.Round(i / 10.0)) * 10;
if (r > 255)
r = 255;
return r;
}
[TestMethod]
public void AverageColorTest_WebExample()
{
Bitmap bm = new Bitmap("C:\\Users\\XXXX\\Desktop\\example1.jpg");
int width = bm.Width;
int height = bm.Height;
int red = 0;
int green = 0;
int blue = 0;
int minDiversion = 15; // drop pixels that do not differ by at least minDiversion between color values (white, gray or black)
int dropped = 0; // keep track of dropped pixels
int bppModifier = bm.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb ? 3 : 4; // cutting corners, will fail on anything else but 32 and 24 bit images
BitmapData srcData = bm.LockBits(new System.Drawing.Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, bm.PixelFormat);
int stride = srcData.Stride;
IntPtr Scan0 = srcData.Scan0;
Dictionary<string, Int64> dicColors = new Dictionary<string, long>(); // color, pixelcount i.e ('#FFFFFF',100);
unsafe
{
byte* p = (byte*)(void*)Scan0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int idx = (y * stride) + x * bppModifier;
red = p[idx + 2];
green = p[idx + 1];
blue = p[idx];
red = RoundColorToGroup(red);
green = RoundColorToGroup(green);
blue = RoundColorToGroup(blue);
if (Math.Abs(red - green) > minDiversion || Math.Abs(red - blue) > minDiversion || Math.Abs(green - blue) > minDiversion)
{
string htmlColorGroup = ColorTranslator.ToHtml(Color.FromArgb(red, green, blue));
if (dicColors.ContainsKey(htmlColorGroup))
{
dicColors[htmlColorGroup]++;
}
else
{
dicColors.Add(htmlColorGroup, 1);
}
}
else
{
dropped++;
}
}
}
}
dicColors = dicColors.OrderByDescending(x => x.Value).ToDictionary(pair => pair.Key, pair => pair.Value);
Console.WriteLine(dicColors.ElementAt(0).Key); // should ouput main color 1
Console.WriteLine(dicColors.ElementAt(1).Key); // should ouput main color 2
Console.WriteLine(dicColors.ElementAt(2).Key); // should ouput main color 3
}
- example1.jpg の出力は (#FF6E8C, #FF6482, #FA6E8C) - 赤/ピンクの 3 階調 - 赤、黒、白である必要があります
- example2.jpg の出力は (#F0C8C8,#C8DC6E,#E6C8C8) - ピンクとグリーンの 2 色 - ライト ピンク、グリーン、ホワイトのはずです
- example3.jpg の出力は (#FFDC50,#640A28,#8C1E3C) - 青の 3 階調 - 青、黄、黒である必要があります
理想的には、背景色 (#FFFFFF) と黒のアウトライン/シェーディングを無視する必要があります。
ここでHTMLの色をオンラインでコピーして貼り付けることができます