Используя C #, есть ли лучший способ преобразовать Windows Bitmap
в a, byte[]
чем сохранить во временный файл и прочитать результат, используя FileStream
?
Используя C #, есть ли лучший способ преобразовать Windows Bitmap
в a, byte[]
чем сохранить во временный файл и прочитать результат, используя FileStream
?
Ответы:
Есть несколько способов.
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, и ее можно легко изменить между сохранением в памяти или на диске.
ImageConverter
метод сохранит изображение в формате Png, что приведет к огромным файлам.
ImageConverter
не соответствует стандарту .net, который вы можете использоватьMemoryStream
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 Framework, и он не идеален для использования с обработкой изображений (это избыточно для преобразования в байт [] по крайней мере), особенно если учесть следующее.
Я взглянул на ImageConverter
код, используемый .Net Framework, и внутри он использует код, почти идентичный тому, который я предоставил выше. Он создает новый MemoryStream
, сохраняет Bitmap
в любом формате, в котором он был, когда вы его предоставили, и возвращает массив. Пропустить дополнительные затраты на создание ImageConverter
класса с помощьюMemoryStream
Вы также можете просто 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
(см .: docs.microsoft.com/en-us/dotnet/api/… )
System.Drawing.Image does not exist
. Так что .. нет, не работает :(
Используйте MemoryStream
вместо a FileStream
, вот так:
MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
ToArray
, нет GetBuffer
.
Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method.
Итак, теперь массив байтов from GetBuffer
будет возвращать изображение плюс неиспользуемые байты, что, вероятно, приведет к повреждению изображения.
Попробуйте следующее:
MemoryStream stream = new MemoryStream();
Bitmap bitmap = new Bitmap();
bitmap.Save(stream, ImageFormat.Jpeg);
byte[] byteArray = stream.GetBuffer();
Убедитесь, что вы используете:
System.Drawing & using System.Drawing.Imaging;
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");