Преобразование растрового изображения в массив байтов
используя 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 фреймворк и его не идеально использовать с обработкой изображений (это перебор для преобразования в байт[] по крайней мере), особенно если учесть следующее.
Я взглянул на
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();