简体   繁体   English

如何在C#中获取位图图像的背景色?

[英]How do I get the background color of Bitmap Image in c#?

I have the following code- 我有以下代码-

Bitmap img = new Bitmap(ControlsMap.BtnYes.CaptureImage());
img.Save(@"E:\images\btnyes.png");

The image is also captured and saved correctly - 图像也被捕获并正确保存-
在此处输入图片说明

I want to get the background color of the image. 我想获取图像的背景色。

I tried several variations of the following line - 我尝试了以下行的几种变体-

var a = img.Palette.Entries;

but I'm unable to get background color of the image. 但我无法获得图像的背景色。 Is there any other way? 还有其他办法吗?

Just iterate over the entire image and keep a count for each found colour, and then take the colour with the largest count. 只需遍历整个图像并为找到的每种颜色计数,然后选择计数最大的颜色即可。

The simplest way to do this is probably with GetPixel, though for large images that may take a long time. 最简单的方法可能是使用GetPixel,尽管对于需要较长时间的大型图像而言。 So instead, you could paste the image on a 32bppARGB image to ensure it's in a specific known format, then use LockBits and Marshal.Copy to get the raw bytes out, then iterate over those bytes, combine them into a colour per four, and check those colours. 因此,您可以将图像粘贴到32bppARGB图像上以确保其具有特定的已知格式,然后使用LockBits和Marshal.Copy提取原始字节,然后遍历这些字节,将它们组合成每四个的颜色,然后检查那些颜色。

For actually getting the maximum I'd use a Dictionary with the colours as keys, and the amounts as values. 为了真正获得最大值,我将使用Dictionary作为颜色,将键作为颜色,将数量作为值。

All together, you get this: 总而言之,您得到以下信息:

public static Color FindMostCommonColor(Image image)
{
    // Avoid unnecessary getter calls
    Int32 height = image.Height;
    Int32 width = image.Width;
    Int32 stride;
    Byte[] imageData;
    // Expose bytes as 32bpp ARGB
    BitmapData sourceData = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    stride = sourceData.Stride;
    imageData = new Byte[stride * bm.Height];
    Marshal.Copy(sourceData.Scan0, imageData, 0, imageData.Length);
    image.UnlockBits(sourceData);
    // Store colour frequencies in a dictionary.
    Dictionary<Color,Int32> colorFreq = new Dictionary<Color, Int32>();
    for (Int32 y = 0; y < height; y++)
    {
        // Reset offset on every line, since stride is not guaranteed to always be width * pixel size.
        Int32 inputOffs = y * stride;
        //Final offset = y * line length in bytes + x * pixel length in bytes.
        //To avoid recalculating that offset each time we just increase it with the pixel size at the end of each x iteration.
        for (Int32 x = 0; x < width; x++)
        {
            //Get colour components out. "ARGB" is actually the order in the final integer which is read as little-endian, so the real order is BGRA.
            Color col = Color.FromArgb(imageData[inputOffs + 3], imageData[inputOffs + 2], imageData[inputOffs + 1], imageData[inputOffs]);
            Color bareCol = Color.FromArgb(255, col);
            // Only look at nontransparent pixels; cut off at 127.
            if (col.A > 127)
            {
                if (!colorFreq.ContainsKey(bareCol))
                    colorFreq.Add(bareCol, 1);
                else
                    colorFreq[bareCol]++;
            }
            // Increase the offset by the pixel width. For 32bpp ARGB, each pixel is 4 bytes.
            inputOffs += 4;
        }
    }
    // Get the maximum value in the dictionary values
    Int32 max = colorFreq.Values.Max();
    // Get the first colour that matches that maximum.
    return colorFreq.FirstOrDefault(x => x.Value == max).Key;
    // In case you want to know if there are multiple with the exact same frequency,
    // this could be expanded to give an array with all maxima like this:
    // Color[] maxCols = colorFreq.Where(x => x.Value == max).Select(kvp => kvp.Key).ToArray();
}

Do note that if the image is jpeg or something, this might not work too well, since it has slight fades on all colours. 请注意,如果图像为jpeg或其他格式,则此效果可能不太好,因为所有颜色都有轻微的褪色。 Then you'll have to somehow do a reduction of similar colours, or a threshold system. 然后,您必须以某种方式减少相似的颜色或阈值系统。 That's a whole different can of worms, though. 但是,那是完全不同的蠕虫病毒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM