在使用C#时,将Windows Bitmap
转换成 byte[]
,有比保存到临时文件并使用 FileStream
读取结果更好的方法吗?
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
这个方案很方便,因为它不需要大量的代码。
内存流
public static byte[] ImageToByte2(Image img)
{
using (var stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
return stream.ToArray();
}
}
这个方法与你的做法相同,只是将文件保存到内存中而不是磁盘。尽管需要更多的代码,但你可以选择ImageFormat选项,并且可以轻松地在保存到内存或磁盘之间进行修改。
使用MemoryStream可能会有所帮助。你可以将它放在扩展方法中:
public static class ImageExtensions
{
public static byte[] ToByteArray(this Image image, ImageFormat format)
{
using(MemoryStream ms = new MemoryStream())
{
image.Save(ms, format);
return ms.ToArray();
}
}
}
你可以像这样使用它:
var image = new Bitmap(10, 10);
// Draw your image
byte[] arr = image.ToByteArray(ImageFormat.Bmp);
对于prestomanifto的答案,我在ImageConverter方面持有部分不同的看法。不要使用ImageConverter。虽然技术上没有问题,但它使用对象的装箱/拆箱让我想起了.NET框架的旧时黑暗地带,并且在图像处理中使用它并不理想(至少将其转换为byte[]是过度设计),特别是考虑到以下事项。
我查看了.Net框架中使用的ImageConverter
代码,它在内部使用几乎与我上面提供的代码完全相同的代码。它创建一个新的MemoryStream
,以您提供的任何格式保存Bitmap
,并返回数组。 通过使用MemoryStream
跳过创建ImageConverter
类的额外开销。
您也可以直接使用Marshal.Copy来复制位图数据,不需要使用中间的内存流等,这样可以快速地进行内存复制。这应该适用于24位和32位位图。
public static byte[] BitmapToByteArray(Bitmap bitmap)
{
BitmapData bmpdata = null;
try
{
bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
int numbytes = bmpdata.Stride * bitmap.Height;
byte[] bytedata = new byte[numbytes];
IntPtr ptr = bmpdata.Scan0;
Marshal.Copy(ptr, bytedata, 0, numbytes);
return bytedata;
}
finally
{
if (bmpdata != null)
bitmap.UnlockBits(bmpdata);
}
}
.
将图像保存到MemoryStream中,然后获取字节数组。
http://msdn.microsoft.com/en-us/library/ms142148.aspx
Byte[] data;
using (var memoryStream = new MemoryStream())
{
image.Save(memoryStream, ImageFormat.Bmp);
data = memoryStream.ToArray();
}
System.Drawing.Image
派生的类型(请参见:https://learn.microsoft.com/en-us/dotnet/api/system.drawing.image.save?view=netframework-4.7.2#System_Drawing_Image_Save_System_IO_Stream_System_Drawing_Imaging_ImageFormat_)工作。 - Chris Baxterusing (var ms = new MemoryStream(previewBinary))
bitmap = (Bitmap)Image.FromStream(ms);
- huha使用MemoryStream
代替FileStream
,像这样:
MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
ToArray
,而不是 GetBuffer
。 - vcsjones请注意,缓冲区包含已分配但未使用的字节。例如,如果将字符串“test”写入MemoryStream对象,则从GetBuffer返回的缓冲区的长度为256,而不是4,其中252个字节未使用。要仅获取缓冲区中的数据,请使用ToArray方法。
因此,从GetBuffer
返回的字节数组将返回图像和未使用的字节,这可能导致图像损坏。 - vcsjones更简单:
return (byte[])System.ComponentModel.TypeDescriptor.GetConverter(pImagen).ConvertTo(pImagen, typeof(byte[]))
尝试以下方法:
MemoryStream stream = new MemoryStream();
Bitmap bitmap = new Bitmap();
bitmap.Save(stream, ImageFormat.Jpeg);
byte[] byteArray = stream.GetBuffer();
请确保使用以下内容:
System.Drawing & using System.Drawing.Imaging;
我相信您可以轻松实现:
ImageConverter converter = new ImageConverter();
var bytes = (byte[])converter.ConvertTo(img, typeof(byte[]));
MemoryStream ms = new MemoryStream();
yourBitmap.Save(ms, ImageFormat.Bmp);
byte[] bitmapData = ms.ToArray();
非常简单,只需在一行中使用:
byte[] imgdata = File.ReadAllBytes(@"C:\download.png");
ImageConverter
isn't .net standard you might useMemoryStream
- Alexandre