c# 来自位图数据的 RGB 值

标签 c# bitmap

我刚开始使用位图并使用每像素 16 位 Format16bppRgb555

我想从位图数据中提取 RGB 值。这是我的代码

static void Main(string[] args)
    {

        BitmapRGBValues();
        Console.ReadKey();
    }


 static unsafe void BitmapRGBValues()
    {

        Bitmap cur = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format16bppRgb555);
        //Capture Screen
        var screenBounds = Screen.PrimaryScreen.Bounds;
        using (var gfxScreenshot = Graphics.FromImage(cur))
        {
            gfxScreenshot.CopyFromScreen(screenBounds.X, screenBounds.Y, 0, 0, screenBounds.Size, CopyPixelOperation.SourceCopy);
        }

        var curBitmapData = cur.LockBits(new Rectangle(0, 0, cur.Width, cur.Height),
                                 ImageLockMode.ReadWrite, PixelFormat.Format16bppRgb555);


        try
        {
            byte* scan0 = (byte*)curBitmapData.Scan0.ToPointer();

            for (int y = 0; y < cur.Height; ++y)
            {
                ulong* curRow = (ulong*)(scan0 + curBitmapData.Stride * y);

                for (int x = 0; x < curBitmapData.Stride / 8; ++x)
                {

                    ulong pixel = curRow[x];

                    //How to get RGB Values  from pixel;







                }

            }


        }
        catch
        {

        }
        finally
        {
            cur.UnlockBits(curBitmapData);

        }


    }

最佳答案

LockBits 实际上可以将您的图像转换为所需的像素格式,这意味着不需要进一步的转换。只需将图像锁定为 Format32bppArgb,您就可以简单地从单个字节中获取颜色值。

BitmapData curBitmapData = cur.LockBits(new Rectangle(0, 0, cur.Width, cur.Height),
    ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Int32 stride = curBitmapData.Stride;
Byte[] data = new Byte[stride * cur.Height];
Marshal.Copy(curBitmapData.Scan0, data, 0, data.Length);
cur.UnlockBits(curBitmapData);

使用此代码,您最终得到字节数组 data,其中填充了 ARGB 格式的图像数据,这意味着颜色分量字节将按顺序 [B, G ,R,A]。请注意,步幅 是为到达图像的下一行而跳过的字节数,因为这总是等于“宽度 * 每个像素的字节数” , 它应该始终被考虑在内。

现在你明白了,你可以用它做任何你想做的事......

Int32 curRowOffs = 0;
for (Int32 y = 0; y < cur.Height; y++)
{
    // Set offset to start of current row
    Int32 curOffs = curRowOffs;
    for (Int32 x = 0; x < cur.Width; x++)
    {
        // ARGB = bytes [B,G,R,A]
        Byte b = data[curOffs];
        Byte g = data[curOffs + 1];
        Byte r = data[curOffs + 2];
        Byte a = data[curOffs + 3];
        Color col = Color.FromArgb(a, r, g, b);

        // Do whatever you want with your colour here
        // ...

        // Increase offset to next colour
        curOffs += 4;
    }
    // Increase row offset
    curRowOffs += stride;
}

您甚至可以编辑字节,然后 build a new image from them如果你愿意的话。

关于c# 来自位图数据的 RGB 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49190596/

相关文章:

android - 位图压缩和异步任务保存期间的问题

c# - 检查元素是否存在或为空

c# - 将类的多个属性传递给函数并返回自定义属性的值

c# - Mvvm Light、UWP 和代码隐藏

java - 在 Activity 之间传递 ResourceId 作为整数

delphi - 如何在无需先绘制的情况下获得位图透明度?

c# - Winforms + mysql + asp.net 对于具有远程访问功能的 C# 数据库应用程序来说足够了吗?

c# - 缓冲 log4net 调试消息以在错误时显示它们?

android - 在 Android 中调整位图大小

java - 如何在 Android 上高效存储位集