c#将图像转换为字节数组

本文关键字:字节 字节数 数组 转换 图像 | 更新日期: 2023-09-27 18:00:17

i正在寻找一个更快的解决方案,使用常规方法将图像转换为字节数组:

   public byte[] imageToByteArray(System.Drawing.Image imageIn)
 {
  MemoryStream ms = new MemoryStream();
  imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
  return  ms.ToArray();
 }

所以我搜索并找到了这个

public static byte[] BitmapToByteArray(Bitmap bitmap)
    {
        BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
        int numbytes = bmpdata.Stride * bitmap.Height;
        numbytes = Math.Abs(numbytes);
        byte[] bytedata = new byte[numbytes];
        IntPtr ptr = bmpdata.Scan0;
        Marshal.Copy(ptr, bytedata, 0, numbytes);
        bitmap.UnlockBits(bmpdata);
        return bytedata;
    }

这是我的电话:

 `   private void Form1_Load(object sender, EventArgs e)
    {
       Bitmap curr = GetDesktopImage();
        byte[] buff = BitmapToByteArray(curr);

        }

我得到了一个表达式arithmetic operation resulted in an overflow,我发现numbofbytes是负的,所以它无法生成数组,所以我使用了Math.Abs(),但我在那一行Marshal.Copy(ptr, bytedata, 0, numbytes);上得到了另一个错误,错误:试图读取或写入受保护的内存。这通常表示其他内存已损坏为什么会这样?GetDesktopImage()是我的一种方法,它使用gdi根据此进行屏幕截图,该方法实际上是(我试图在picturebox上显示),但我在尝试转换为字节时遇到了奇怪的错误。。

这是GetDesktopImage()

 public static Bitmap GetDesktopImage()
    {
        //In size variable we shall keep the size of the screen.
        SIZE size;
        //Variable to keep the handle to bitmap.
        IntPtr hBitmap;
        IntPtr hDC = PlatformInvokeUSER32.GetDC(PlatformInvokeUSER32.GetDesktopWindow());
        IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);
        size.cx = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CXSCREEN);
        size.cy = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CYSCREEN);
        hBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, size.cx, size.cy);
        if (hBitmap != IntPtr.Zero)
        {
            IntPtr hOld = (IntPtr)PlatformInvokeGDI32.SelectObject(hMemDC, hBitmap);
            PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, PlatformInvokeGDI32.SRCCOPY);
            PlatformInvokeGDI32.SelectObject(hMemDC, hOld);
            PlatformInvokeGDI32.DeleteDC(hMemDC);
            PlatformInvokeUSER32.ReleaseDC(PlatformInvokeUSER32.GetDesktopWindow(), hDC);
            Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap);
            PlatformInvokeGDI32.DeleteObject(hBitmap);
            GC.Collect();
            return bmp;
        }

        return null;
    }

c#将图像转换为字节数组

对于负的步幅,MSDN文档说:

步长是一行像素(扫描线)的宽度,四舍五入到四字节边界。如果步幅为正,则位图是自上而下的。如果步幅为负,则位图是自下而上的。

位图是自下而上的。请看下面这个不错的解释:https://msdn.microsoft.com/en-us/library/windows/desktop/aa473780(v=vs.85).aspx

要复制字节,您需要计算起始地址,如下所示:https://stackoverflow.com/a/17116072/200443.

如果要反转字节顺序,则需要一次复制一行。