Convertir un mapa de bits en una matriz de bytes
Usando C#, ¿hay una mejor manera de convertir Windows Bitmap
a byte[]
que guardarlo en un archivo temporal y leer el resultado usando un FileStream
?
Hay un par de maneras.
Convertidor de imágenes
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();
}
}
Esto es equivalente a lo que estás haciendo, excepto que el archivo se guarda en la memoria en lugar de en el disco. Aunque más código tienes la opción de ImageFormat y se puede modificar fácilmente entre guardar en la memoria o en el disco.
Fuente: http://www.vcskicks.com/image-to-byte.php
Un MemoryStream puede resultar útil para esto. Podrías 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 a ImageConverter. No utilice ImageConverter. No hay nada técnicamente malo en ello, pero simplemente el hecho de que usa boxing/unboxing de un objeto me dice que es código de los viejos lugares oscuros del marco .NET y no es ideal para usarlo con procesamiento de imágenes (es excesivo convertirlo a un byte). [] al menos), especialmente si se considera lo siguiente.
Eché un vistazo al ImageConverter
código utilizado por .Net framework e internamente utiliza un código casi idéntico al que proporcioné anteriormente. Crea un nuevo MemoryStream
, lo guarda Bitmap
en el formato en el que se encontraba cuando lo proporcionó y devuelve la matriz. Evite la sobrecarga adicional de crear una ImageConverter
clase usandoMemoryStream
También puede simplemente Marshal. Copiar los datos del mapa de bits. Sin flujo de memoria intermediario, etc. y una copia de memoria rápida. Esto debería funcionar tanto en mapas de bits de 24 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);
}
}
.