Usando C #, ¿hay una mejor manera de convertir un Windows Bitmap
a un byte[]
archivo que guardar en un archivo temporal y leer el resultado usando un FileStream
?
Usando C #, ¿hay una mejor manera de convertir un Windows Bitmap
a un byte[]
archivo que guardar en un archivo temporal y leer el resultado usando un FileStream
?
Respuestas:
Hay un par de maneras.
ImageConverter
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
Este es conveniente porque no requiere mucho código.
Flujo de memoria
public static byte[] ImageToByte2(Image img)
{
using (var stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
return stream.ToArray();
}
}
Este es equivalente a lo que está haciendo, excepto que el archivo se guarda en la memoria en lugar de en el disco. Aunque tiene más código, tiene la opción de ImageFormat y puede modificarse fácilmente entre guardarlo en la memoria o en el disco.
ImageConverter
método guardará la imagen como Png, lo que dará como resultado archivos ENORMES.
ImageConverter
no es el estándar .net que podrías usarMemoryStream
Un MemoryStream puede ser útil para esto. Podría ponerlo en un método de extensión:
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();
}
}
}
Podrías usarlo como:
var image = new Bitmap(10, 10);
// Draw your image
byte[] arr = image.ToByteArray(ImageFormat.Bmp);
Estoy parcialmente en desacuerdo con la respuesta de prestomanifto con respecto al ImageConverter. No use ImageConverter. No hay nada técnicamente malo en ello, pero el simple hecho de que use boxing / unboxing from object me dice que es código de los viejos lugares oscuros del marco .NET y no es ideal para usar con el procesamiento de imágenes (es excesivo para convertir a un byte [] al menos), especialmente cuando considera lo siguiente.
Eché un vistazo al ImageConverter
código utilizado por el marco .Net, e internamente usa un código casi idéntico al que proporcioné anteriormente. Crea uno nuevo MemoryStream
, guarda el Bitmap
formato en el que estaba cuando lo proporcionó y devuelve la matriz. Omita la sobrecarga adicional de crear una ImageConverter
clase utilizandoMemoryStream
También puede simplemente Marshal. Copie los datos del mapa de bits. Sin memoria intermedia, etc. y una copia rápida de la memoria. Esto debería funcionar tanto en mapas de bits de 24 bits como de 32 bits.
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);
}
}
.
Guarde la imagen en un MemoryStream y luego tome la matriz de bytes.
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
(ver: docs.microsoft.com/en-us/dotnet/api/… )
System.Drawing.Image does not exist
. Entonces ... no, no funciona :(
Use un en MemoryStream
lugar de un FileStream
, así:
MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
ToArray
, no 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.
ahora la matriz de bytes de GetBuffer
devolverá la imagen más los bytes no utilizados, lo que probablemente dará como resultado una imagen corrupta.
Intenta lo siguiente:
MemoryStream stream = new MemoryStream();
Bitmap bitmap = new Bitmap();
bitmap.Save(stream, ImageFormat.Jpeg);
byte[] byteArray = stream.GetBuffer();
Asegúrate de estar usando:
System.Drawing & using System.Drawing.Imaging;
MemoryStream ms = new MemoryStream();
yourBitmap.Save(ms, ImageFormat.Bmp);
byte[] bitmapData = ms.ToArray();
Más simple:
return (byte[])System.ComponentModel.TypeDescriptor.GetConverter(pImagen).ConvertTo(pImagen, typeof(byte[]))
Muy simple usar esto solo en una línea:
byte[] imgdata = File.ReadAllBytes(@"C:\download.png");