Використовуючи C #, чи є кращий спосіб перетворити Windows Bitmap
на файл, byte[]
ніж збереження у тимчасовий файл та зчитування результату за допомогою FileStream
?
Використовуючи C #, чи є кращий спосіб перетворити Windows Bitmap
на файл, 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);
Я частково не погоджуюся з відповіддю престоманіфто щодо ImageConverter. Не використовуйте ImageConverter. З цим нічого погано технічно, але просто той факт, що він використовує бокс / розблокування від об'єкта, говорить про те, що це код зі старих темних місць рамки .NET і його не ідеально використовувати для обробки зображень (це надмірність для перетворення в байт [] принаймні), особливо якщо врахувати наступне.
Я поглянув на ImageConverter
код, який використовується .Net Framework, і внутрішньо він використовує код, майже ідентичний тому, який я подав вище. Він створює новий MemoryStream
, зберігає Bitmap
в будь-якому форматі він був, коли ви його надали, і повертає масив. Пропустіть додаткові накладні витрати на створення ImageConverter
класу за допомогою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();
}
System.Drawing.Image
(див .: docs.microsoft.com/en-us/dotnet/api/… )
System.Drawing.Image does not exist
. Отже .. ні, не працює :(
Використовуйте MemoryStream
замість 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.
Тепер байтовий масив від 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");