2011-09-16 34 views
0

我正在創建掃描圖像所有像素的程序,並且每當它找到包含粉紅色的像素時。它使像素變黑。但是當圖像上有兩個像素時,它似乎沒有找到一個粉紅色的像素。我不知道我是否正確使用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); 

回答

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