2012-03-17 5 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는 16bpp 인코딩입니다. 24bpp 이미지는 R, G 및 B에 대해 8 비트를 가지므로 특별한 것은 필요 없습니다. –

+0

woops, 당신의 권리, 나는 24 비트를 가져 와서 16 비트 컬러의 24 비트 이미지가되도록 조작하고 싶었습니다. 미안하지만, 고쳐 줄 것입니다. – BigBug

+0

잘 모르겠습니다. 나는 당신이 원한다고 추측하고 R과 B는 0xf8으로, G는 0xfc로 낮은 비트를 0으로 설정한다. & 연산자를 사용하십시오. 특히 LCD 모니터에서 그 차이를보기가 어려울 것입니다. 가장 빠른 방법은 이미지를 16bpp 비트 맵으로 Graphics.DrawImage()하는 것입니다. –

답변

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

+0

R 값 내에서 이미지의 각 픽셀마다 다른 2 비트를 말하고 싶습니다. – BigBug

1

RGB24는 색상 채널 당 1 바이트이므로 이미 가지고있는 데이터에서 RGB24를 추출하려면 조금만 움직일 필요가 없습니다. "비트 가져 오기"는 이미 값을 설정할 수 있으므로 실제로 의미가 없습니다.

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

원본 이미지 청색 채널에 새로운 이미지 청색 채널을 설정하지만, 채널이 반전한다 1.

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

에 고차 비트를 설정한다.

그래서 이미 가지고있는 데이터에 비트 연산자 (| & >> < < ^)를 사용해야합니다.

관련 문제