2016-07-11 3 views
0

나는 다음과 같은 방법,C#에서 비트 맵을 1D 바이트 배열로 변환하거나 그 반대로 변환 할 수 있습니까?

public static byte[] BitmapToByteArray(Bitmap image) 
     { 
      byte[] returns = null; 
      if (image.PixelFormat == PixelFormat.Format8bppIndexed) 
      { 
       BitmapData bitmapData = image.LockBits(
               new Rectangle(0, 0, image.Width, image.Height), 
               ImageLockMode.ReadWrite, 
               image.PixelFormat); 
       int noOfPixels = image.Width * image.Height; 
       int colorDepth = Bitmap.GetPixelFormatSize(image.PixelFormat); 
       int step = colorDepth/8; 
       byte[] bytes = new byte[noOfPixels * step]; 
       IntPtr address = bitmapData.Scan0; 
       Marshal.Copy(address, bytes, 0, bytes.Length); 
       //////////////////////////////////////////////// 
       /// 
       returns = (byte[])bytes.Clone(); 
       /// 
       //////////////////////////////////////////////// 
       Marshal.Copy(bytes, 0, address, bytes.Length); 
       image.UnlockBits(bitmapData); 
      } 
      else 
      { 
       throw new Exception("8bpp indexed image required"); 
      } 
      return returns; 
     } 

그리고, 그들은 작동하지 않는 것 같다

public static Bitmap ByteArrayToBitmap(byte[] bytes, int width, int height, PixelFormat pixelFormat) 
     { 
      Bitmap bitmap = new Bitmap(width, height, pixelFormat); 
      BitmapData bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); 
      int colorDepth = Bitmap.GetPixelFormatSize(pixelFormat); 
      int noOfChannels = colorDepth/8; 
      IntPtr address = bitmapData.Scan0; 
      ////////////////////////////////////////////////////////////// 
      // 
      Marshal.Copy(bytes, 0, address, width * height * noOfChannels); 
      // 
      ////////////////////////////////////////////////////////////// 
      bitmap.UnlockBits(bitmapData); 

      return bitmap; 
     } 

enter image description here

문제가 있었다 당신은 어떻게 생각했습니다 썼다?

N.B.

드라이버 프로그램,

public class MainClass 
{ 
    public static void Main(string [] args) 
    { 
     Bitmap inputBmp = (Bitmap)Bitmap.FromFile(@"cameraman.gif"); 

     byte[] bytes = Converter.BitmapToByteArray(inputBmp);//byte[65536] 

     Bitmap outputBmp = Converter.ByteArrayToBitmap(bytes, inputBmp.Width, inputBmp.Height, PixelFormat.Format8bppIndexed); 

     PictureDisplayForm f = new PictureDisplayForm(inputBmp, outputBmp); 
     f.ShowDialog(); 
    } 
} 
+2

파일 헤더, 비트 맵 헤더 및 팔레트가 포함되어 있습니다. 필요에 따라 BMP 파일 형식. "예외"가 무엇을 의미하는지 짐작할 수는 없겠지만이 여분의 데이터를 이미지 픽셀로 해석하면 무언가가 잘못 될 수도 있습니다. –

+0

두 번째 방법은 원시 파일을 버퍼에 덤프합니다. 비트 맵을 산출하기 위해 해석되어야합니다. –

답변

1

좋아요.

나는 그것을 풀었다.

public static byte[] BitmapToByteArray(Bitmap image) 
     { 
      byte[] returns = null; 
      if (image.PixelFormat == PixelFormat.Format8bppIndexed) 
      { 
       BitmapData bitmapData = image.LockBits(
               new Rectangle(0, 0, image.Width, image.Height), 
               ImageLockMode.ReadWrite, 
               image.PixelFormat); 
       int noOfPixels = image.Width * image.Height; 
       int colorDepth = Bitmap.GetPixelFormatSize(image.PixelFormat); 
       int step = colorDepth/8; 
       byte[] bytes = new byte[noOfPixels * step]; 
       IntPtr address = bitmapData.Scan0; 
       Marshal.Copy(address, bytes, 0, bytes.Length); 
       //////////////////////////////////////////////// 
       /// 
       returns = (byte[])bytes.Clone(); 
       /// 
       //////////////////////////////////////////////// 
       Marshal.Copy(bytes, 0, address, bytes.Length); 
       image.UnlockBits(bitmapData); 
      } 
      else 
      { 
       throw new Exception("8bpp indexed image required"); 
      } 
      return returns; 
     } 

     public static Bitmap ByteArray1dToBitmap(byte[] bytes, int width, int height) 
     { 
      PixelFormat pixelFormat = PixelFormat.Format8bppIndexed; 
      Bitmap bitmap = new Bitmap(width, height, pixelFormat); 

      // Set the palette for gray shades 
      ColorPalette pal = bitmap.Palette; 
      for (int i = 0; i < pal.Entries.Length; i++) 
      { 
       pal.Entries[i] = Color.FromArgb(i, i, i); 
      } 
      bitmap.Palette = pal; 

      BitmapData bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, pixelFormat); 
      int colorDepth = Bitmap.GetPixelFormatSize(pixelFormat); 
      int noOfChannels = colorDepth/8; 

      unsafe 
      { 
       byte* address = (byte*)bitmapData.Scan0; 
       int area = width * height; 
       int size = area * noOfChannels; 
       for (int i = 0; i < area; i++) 
       { 
        address[i] = bytes[i];//262144 bytes 
       } 
      } 

      ////////////////////////////////////////////////////////////// 
      bitmap.UnlockBits(bitmapData); 

      return bitmap; 
     } 
+0

실제로 보폭을 고려해야합니다 ... 저장된 이미지가 압축되어 라인을 4 바이트로 정렬하지 않으면 문제가 생길 수 있습니다. 또한 색상 깊이를 8로 나누기 때문에 4bpp 또는 1bpp 인덱싱 된 이미지에서는 계산 방법이 작동하지 않습니다. – Nyerguds

관련 문제