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;
}
对于负的步幅,MSDN文档说:
步长是一行像素(扫描线)的宽度,四舍五入到四字节边界。如果步幅为正,则位图是自上而下的。如果步幅为负,则位图是自下而上的。
位图是自下而上的。请看下面这个不错的解释:https://msdn.microsoft.com/en-us/library/windows/desktop/aa473780(v=vs.85).aspx
要复制字节,您需要计算起始地址,如下所示:https://stackoverflow.com/a/17116072/200443.
如果要反转字节顺序,则需要一次复制一行。