2012-03-17 75 views
2

我編寫了下面的代碼來操作圖像的顏色。我想以某種方式撕開圖像的每個像素。因此,對於每個像素,我想訪問5位紅色,6位綠色和5位藍色(按照16位圖像)。我如何改變我的代碼來做到這一點?我想我必須以某種方式將我設置的字節值轉換爲位?字節到BMP中獲取RGB的位

任何幫助將是偉大的。

 private Bitmap InvertBitmap(Bitmap bmp) 
     { 

      unsafe 
      { 
       //create an empty bitmap the same size as original 
       Bitmap newBitmap = new Bitmap(bmp.Width, bmp.Height); 

      //lock the original bitmap in memory 
      System.Drawing.Imaging.BitmapData originalData = bmp.LockBits(
       new Rectangle(0, 0, bmp.Width, bmp.Height), 
       System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 

      //lock the new bitmap in memory 
      System.Drawing.Imaging.BitmapData newData = newBitmap.LockBits(
       new Rectangle(0, 0, bmp.Width, bmp.Height), 
       System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 

      //set the number of bytes per pixel 
      int pixelSize = 3; 

      for (int y = 0; y < bmp.Height; y++) 
      { 
       //get the data from the original image 
       byte* originalImageRow = (byte*)originalData.Scan0 + (y * originalData.Stride); 

       //get the data from the new image 
       byte* newImageRow = (byte*)newData.Scan0 + (y * newData.Stride); 

       for (int x = 0; x < bmp.Width; x++) 
       { 

        //set the new image's pixel to the inverted version 

        newImageRow[x * pixelSize] = (byte)(255 - originalImageRow[x * pixelSize + 0]); //B 
        newImageRow[x * pixelSize + 1] = (byte)(255 - originalImageRow[x * pixelSize + 1]); //G 
        newImageRow[x * pixelSize + 2] = (byte)(255 - originalImageRow[x * pixelSize + 2]); //R 
       } 
      } 

      //unlock the bitmaps 
      newBitmap.UnlockBits(newData); 
      bmp.UnlockBits(originalData); 

      return newBitmap; 
     } 
} 
+0

565是16-bpp編碼。 24-bpp圖像有8位用於R,G和B,沒有什麼特別的需要。 – 2012-03-17 01:34:27

+0

woops,你的權利,我想採取24位和操縱它,以便它是一個16位顏色的24位圖像,對不起,將修復 – BigBug 2012-03-17 01:52:39

+0

不知道這是否合理。我想你想和R和B與0xf8和G與0xfc設置低位爲零。使用&運算符。很難看出差異,特別是在液晶顯示器上。最快的方法就是將Graphics.DrawImage()圖像轉換爲16bpp位圖。 – 2012-03-17 01:55:19

回答

2

如果有一個16位的整數x,則可以通過第一掩蔽那些位用二進制AND,那麼結果移位提取在其內的位的範圍。像這樣:

int x = 33808; // 1000010000010000, for testing 

int r = (x & 63488) >> 11; // 63488 = 1111100000000000 
int g = (x & 2016) >> 5;  // 2016 = 0000011111100000 
int b = (x & 31);    // 31 = 0000000000011111 

// r = 10000 
// g = 100000 
// b = 10000 

我希望有幫助。

+0

嗯,所以你的意思是將所有R G和B值存儲在16位整數?然後從那裏幾乎解析int獲得位? – BigBug 2012-03-17 00:46:39

+0

我希望能夠將R值內的2位更改爲圖像每個像素中不同的東西。 – BigBug 2012-03-17 00:47:07

1

RGB24是每個顏色通道1個字節,所以你不需要做任何操作就可以從你已有的數據中提取它們。 「獲取位」並沒有什麼意義,因爲你可以設置它們的值,例如

newImageRow[x * pixelSize] = (byte)(originalImageRow[x * pixelSize + 0] | 0x80); //B 

將設置新的圖像藍色通道與原始圖像藍色通道,但將高階位設置爲1。

newImageRow[x * pixelSize] = (byte)(originalImageRow[x * pixelSize + 0]^0xFF); //B 

將反轉信道。

所以你真的只需要使用按位運算符(| & >> < < ^)對你已有的數據。