【问题标题】:Locking Bits Fails To Detect Pixels锁定位无法检测像素
【发布时间】:2011-09-16 22:09:55
【问题描述】:

我正在创建一个程序来扫描图像的所有像素,并在找到包含粉红色的像素时进行扫描。它使像素变黑。但是当图像上有两个时,它似乎没有找到粉红色的像素。我不知道我是否正确使用了 LockBits,也许我用错了。谁能帮我解决这个问题,我将不胜感激。

下面是代码:

            Bitmap bitmap = pictureBox1.Image as Bitmap;
            System.Drawing.Imaging.BitmapData d = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat);
            IntPtr ptr = d.Scan0;
            byte[] rgbs = new byte[Math.Abs(d.Stride) * bitmap.Height];
            Marshal.Copy(ptr, rgbs, 0, rgbs.Length);
            Graphics g = pictureBox1.CreateGraphics();
            for (int index = 2; index < rgbs.Length; index += 3)
            {


                if (rgbs[index] == 255 &&  rgbs[index - 1] == 0 && rgbs[index - 2] == 255) // If color = RGB(255, 0, 255) Then ...
                {
                     // This never gets executed!
                     rgbs[index] = 0;
                     rgbs[index - 1] = 0;
                     rgbs[index - 2] = 0;

                }
            }
            Marshal.Copy(rgbs, 0, ptr, rgbs.Length); // Copy rgb values back to the memory location of the bitmap.
            pictureBox1.Image = bitmap;
            bitmap.UnlockBits(d); 

【问题讨论】:

    标签: c# .net bitmap lockbits


    【解决方案1】:

    您不需要将像素数据复制到数组中。 LockBits 的重点是它让您可以直接(不安全)访问内存。您可以迭代像素并在找到它们时更改它们。您需要知道图像的格式才能成功执行此操作。

      BitmapData bmd=bm.LockBits(new Rectangle(0, 0, 10, 10), 
                           ImageLockMode.ReadOnly, bm.PixelFormat);
      // Blue, Green, Red, Alpha (Format32BppArgb)
      int pixelSize=4;
    
      for(int y=0; y<bmd.Height; y++)
      {
        byte* row=(byte *)bmd.Scan0+(y*bmd.Stride);
        for(int x=0; x<bmd.Width; x++) 
        {
          int offSet = x*pixelSize;
          // read pixels
          byte blue = row[offSet];
          byte green = row[offSet+1];
          byte red = row[offSet+2];
          byte alpha = row[offSet+3];
    
          // set blue pixel
          row[x*pixelSize]=255;
        }
      }
    

    在 VB 中比在 C# 中要复杂一些,因为 VB 不知道指针,并且需要使用 marshal 类来访问非托管数据。这是一些示例代码。 (出于某种原因,我最初认为这是一个 VB 问题)。

      Dim x As Integer
      Dim y As Integer
      ' Blue, Green, Red, Alpha (Format32BppArgb)
      Dim PixelSize As Integer = 4 
      Dim bmd As BitmapData = bm.LockBits(new Rectangle(0, 0, 10, 10),
                                          ImageLockMode.ReadOnly, bm.PixelFormat)
    
      For y = 0 To bmd.Height - 1
        For x = 0 To bmd.Width - 1
          Dim offSet As Int32 = (bmd.Stride * y) + (4 * x)
          ' read pixel data
          Dim blue As Byte = Marshal.ReadByte(bmd.Scan0, offSet)
          Dim green As Byte = Marshal.ReadByte(bmd.Scan0, offSet + 1)
          Dim red As Byte = Marshal.ReadByte(bmd.Scan0, offSet + 2)
          Dim alpha As Byte = Marshal.ReadByte(bmd.Scan0, offSet + 3)
          ' set blue pixel
          Marshal.WriteByte(bmd.Scan0, offSet , 255)
        Next
      Next
    

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 1970-01-01
      • 2011-06-06
      • 1970-01-01
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多