2011-02-24 3 views
0

이것은 내 코드 here에서 수집 한 것입니다.C의 이미지 반전

private unsafe byte[] BmpToBytes_Unsafe(Bitmap bmp) 

     { 

      BitmapData bData = bmp.LockBits(new Rectangle(0,0,1000,1000), 

       ImageLockMode.ReadOnly, 

       PixelFormat.Format24bppRgb); 

      // number of bytes in the bitmap 



      int byteCount = bData.Stride * bmp.Height; 

      byte[] bmpBytes = new byte[byteCount]; 



      // Copy the locked bytes from memory 





      Marshal.Copy(bData.Scan0, bmpBytes, 0, byteCount); 

      Marshal. 



      // don't forget to unlock the bitmap!! 

      bmp.UnlockBits(bData); 



      return bmpBytes; 

     } 

나는 위에서 언급 한 기능에서 바이트를 가져 와서 추가 처리없이 표시합니다. 하지만 출력에서 ​​거꾸로 된 이미지를 얻습니다. 누군가 설명 할 수 있니?

답변

1

"거꾸로"라고 말하면 거꾸로 된 것입니까?

해당 코드를 게시 한 사람의 "l33t hax0r skillz"에 의존 할 수 없습니다. 비트 맵이 메모리에서 어떻게 처리되는지에 대한 중요한 정보가 부족합니다.

비트 맵에서 데이터를 읽을 때 하나의 청크에서 전체를 읽을 수 없습니다. 데이터는 라인에 저장되며 라인은 먼저 상단 라인 또는 하단 라인 중 하나로 저장 될 수 있습니다. 또한 짝수 단어 경계에서 각 줄을 가져 오기 위해 줄 사이에 패딩이있을 수 있습니다.

Scan0 속성은 첫 번째 줄의 시작 부분에 대한 포인터이고 Stride 속성은 다음 줄의 시작 부분에 대한 오프셋입니다. Width 등록 정보를 사용하여 각 행에 얼마나 많은 데이터가 있는지 확인할 수 있습니다.

그래서, 당신은 한 번에 하나의 라인으로 데이터를 복사 할 수 있습니다

int lineSize = bData.Width * 3; 
int byteCount = lineSize * bData.Height; 
byte[] bmpBytes = new byte[byteCount]; 

IntPtr scan = bData.Scan0; 
for (int i = 0; i < bData.Height; i++) { 
    Marshal.Copy(scan, bmpBytes[i * lineSize], 0, lineSize); 
    scan += bData.Stride; 
} 
+0

빠른 노트는,이 메소드가 스레드에서 호출 한 스레드 만이 방법을 액세스합니다. 이 방법은 스레드로부터 안전해야한다고 생각하십니까? – nightWatcher

+0

@nightWatcher : 하나의 스레드 만 메서드를 호출하면 스레드를 안전하게 만들 필요가 없습니다. – Guffa

1

정상입니다. 비트 맵은 거꾸로 저장됩니다. 하단 스캔 라인은 BitmapData.Scan0입니다. 당신은 한 번에 하나의 주사선을 복사함으로써이를 수정해야 할 것입니다. 어떻게 표시하는지에 달려 있습니다.

0

24bpp windows 비트 맵은 내부적으로 픽셀 색을 RGB가 아닌 BGR 순서로 유지합니다.