Convertir un mapa de bits en una matriz de bytes

Resuelto Jeremy McGee asked hace 13 años • 10 respuestas

Usando C#, ¿hay una mejor manera de convertir Windows Bitmapa byte[]que guardarlo en un archivo temporal y leer el resultado usando un FileStream?

Jeremy McGee avatar Sep 08 '11 22:09 Jeremy McGee
Aceptado

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

prestomanifesto avatar Sep 08 '2011 15:09 prestomanifesto

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 ImageConvertercódigo utilizado por .Net framework e internamente utiliza un código casi idéntico al que proporcioné anteriormente. Crea un nuevo MemoryStream, lo guarda Bitmapen el formato en el que se encontraba cuando lo proporcionó y devuelve la matriz. Evite la sobrecarga adicional de crear una ImageConverterclase usandoMemoryStream

Christopher Currens avatar Sep 08 '2011 15:09 Christopher Currens

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);
    }

}

.

deegee avatar Jun 21 '2013 21:06 deegee