代码之家  ›  专栏  ›  技术社区  ›  Azar Shaikh

位图数据中的c#RGB值

  •  2
  • Azar Shaikh  · 技术社区  · 8 年前

    我对使用位图和每像素使用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);
    
            }
    
    
        }
    
    1 回复  |  直到 8 年前
        1
  •  5
  •   Nyerguds    8 年前

    锁具实际上可以 转换 将图像转换为所需的像素格式,这意味着不需要进一步转换。只需将图像锁定为 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]的顺序排列。请注意 stride 是要跳到图像上的下一行的字节数 始终等于“宽度*每像素字节数”,应始终将其考虑在内。

    现在你知道了,你可以用它做任何你想做的事。。。

    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 如果你愿意的话。