Преобразование растрового изображения в массив байтов
используя C#, есть ли лучший способ конвертировать Windows Bitmap
до byte[]
чем сохранение во временный файл и чтение результатов с помощью FileStream
?
10 ответов
есть несколько способов.
ImageConverter
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, и его можно легко изменить между сохранением в памяти или на диске.
A потоке 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);
Я частично не согласен с ответом престоманифто в отношении ImageConverter. не используйте ImageConverter. в этом нет ничего технически неправильного, но просто тот факт, что он использует бокс/распаковку из объекта, говорит мне, что это код из старых темных мест .NET framework и его не идеально использовать с обработкой изображений (это перебор для преобразования в байт [], по крайней мере), особенно если вы считаете следующее.
Я взглянул на ImageConverter
код, используемый .NET framework, и внутренне он использует код, почти идентичный тому, который я предоставил выше. Он создает новый MemoryStream
, сохраняет Bitmap
в любом формате, в котором он был, когда вы его предоставили, и возвращает массив. Пропустите дополнительные накладные расходы на создание ImageConverter
класса с помощью MemoryStream
вы также можете просто Маршал.Скопируйте растровые данные. Нет промежуточного memorystream и т. д. и быстрая копия на память. Это должно работать как на 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();
}
использовать MemoryStream
вместо FileStream
, например:
MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
попробуйте следующее:
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();
более простой:
return (byte[])System.ComponentModel.TypeDescriptor.GetConverter(pImagen).ConvertTo(pImagen, typeof(byte[]))
очень просто используйте это только в одной строке:
byte[] imgdata = File.ReadAllBytes(@"C:\download.png");