如何在C#中从图像的特定区域获取颜色

问题描述 投票:1回答:2

我正在尝试从图像的特定区域获得颜色。 enter image description here

假设这是图像,我想在图像内部获取颜色。(结果应为上述图像的红色)此颜色可能在图像中的位置不同。因为我不知道颜色的确切位置,所以我无法获得确切的结果。

直到现在,我手动裁切了x和y位置的图像,然后裁切了图像,得到裁切图像的平均颜色。但是我知道,这不是确切的颜色。

我尝试过的:

private RgbDto GetRGBvalueCroppedImage(Image croppedImage)
        {
        var avgRgb = new RgbDto();
        var bm = new Bitmap(croppedImage);


        BitmapData srcData = bm.LockBits(
            new Rectangle(0, 0, bm.Width, bm.Height),
            ImageLockMode.ReadOnly,
            PixelFormat.Format32bppArgb);

        int stride = srcData.Stride;

        IntPtr Scan0 = srcData.Scan0;

        long[] totals = new long[] { 0, 0, 0 };

        int width = bm.Width;
        int height = bm.Height;

        unsafe
        {
            byte* p = (byte*)(void*)Scan0;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    for (int color = 0; color < 3; color++)
                    {
                        int idx = (y * stride) + x * 4 + color;

                        totals[color] += p[idx];
                    }
                }
            }
        }

        avgRgb.avgB = (int)totals[0] / (width * height);
        avgRgb.avgG = (int)totals[1] / (width * height);
        avgRgb.avgR = (int)totals[2] / (width * height);

        return avgRgb;
    }

我如何获得准确的作物位置?可能是我可以将图像转换为字节数组,然后可以找到不同的颜色并确定其位置,然后进行裁切。但是我不知道该怎么做。

c# image
2个回答
3
投票

您可以使用这种扩展方法来获得图像区域中的主色,以防它们不尽相同

public static Color GetDominantColor(this Bitmap bitmap, int startX, int startY, int width, int height) {

    var maxWidth = bitmap.Width;
    var maxHeight = bitmap.Height;

    //TODO: validate the region being requested

    //Used for tally
    int r = 0;
    int g = 0;
    int b = 0;
    int totalPixels = 0;

    for (int x = startX; x < (startX + width); x++) {
        for (int y = startY; y < (startY + height); y++) {
            Color c = bitmap.GetPixel(x, y);

            r += Convert.ToInt32(c.R);
            g += Convert.ToInt32(c.G);
            b += Convert.ToInt32(c.B);

            totalPixels++;
        }
    }

    r /= totalPixels;
    g /= totalPixels;
    b /= totalPixels;

    Color color = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);

    return color;
}

然后您可以像使用它

Color pixelColor = myBitmap.GetDominantColor(xPixel, yPixel, 5, 5); 

还有改进的空间,例如使用“点和大小”,甚至使用“矩形”

public static Color GetDominantColor(this Bitmap bitmap, Rectangle area) {
    return bitmap.GetDominantColor(area.X, area.Y, area.Width, area.Height);
}

并点击此链接:https://www.c-sharpcorner.com/UploadFile/0f68f2/color-detecting-in-an-image-in-C-Sharp/


1
投票

如果要获得图像颜色,则根本不需要进行任何裁剪。只需循环显示图像像素并找到两种不同的颜色即可。 (假设您已经知道该图像将恰好具有2种颜色,如您在评论中所述)。我已经写了一个小函数来实现。但是,我没有在IDE中对其进行测试,因此会出现一些小错误:

private static Color[] GetColors(Image image)
{
    var bmp = new Bitmap(image);
    var colors = new Color[2];
    colors[0] = bmp.GetPixel(0, 0);
    for (int i = 0; i < bmp.Width; i++)
    {
        for (int j = 0; j < bmp.Height; j++)
        {
            Color c = bmp.GetPixel(i, j);
            if (c == colors[0]) continue;
            colors[1] = c;
            return colors;
        }   
    }
    return colors;
}
© www.soinside.com 2019 - 2024. All rights reserved.