简体   繁体   中英

Why is the size of byte array not bmp.Width * bmp.Height * 4 after converting a Bitmap into a byte array?

I have been trying to understand why it is that whenever I convert a bitmap into a byte array using these methods (that I found on stack overflow):

public byte[] ImageToByte(Image img)
{
    ImageConverter converter = new ImageConverter();
    return (byte[])converter.ConvertTo(img, typeof(byte[]));
}

public static byte[] BitmapToByteArray(Bitmap bitmap)
{
    BitmapData 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);

    bitmap.UnlockBits(bmpdata);

    return bytedata;
}

public static byte[] ImageToByte2(Image img)
{
    byte[] byteArray = new byte[0];
    using(MemoryStream stream = new MemoryStream())
    {
        img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
        stream.Close();

        byteArray = stream.ToArray();
    }
    return byteArray;
}

the array size that I get is not bmp.Width * bmp.Height * 4. I mean, 1 pixel is 4 bytes, and there are bmp.Width * bmp.Height pixels in a bitmap. In fact each one of these 3 methods gives different results. So how do I get a byte array of size bmp.Width * bmp.Heigh * 4 from a Bitmap?

I want to get a byte array of exactly that size because I want to use it to process the image itself, otherwise, if I don't know the bounds, I get an out of bounds exception.

ImageToByte returns you the whole file as a byte array.

BitmapToByteArray returns you only the Image Data described by the bitmap.

ImageToByte2 returns you the whole file converted to PNG as a byte array.

Please note that BMP file format is not composed by just Image Data 位图文件格式

It looks to me as if you're saving as a single dimension byte array. All you can do is byteArray.Length to return the number of bytes stored in the array. The reason you're getting different results is because they're each saving in different formats. One uses a native in memory Image format, the other uses a png and one appears to use a bitmap.

That's why your results are different. If you want to calculate a file size based on your format, write a function to do it. You already have the algorithm width*height*4. Feed it a bitmap.

public static byte[] BitmapToByteArray(Bitmap bitmap)
{
    BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    int numbytes = bmpdata.Stride * bitmap.Height;
    byte[] bytedata = new byte[numbytes];
    IntPtr ptr = bmpdata.Scan0;

    Marshal.Copy(ptr, bytedata, 0, numbytes);

    bitmap.UnlockBits(bmpdata);

    return bytedata;
}

Specifying 'PixelFormat.Format32bppArgb' in 'LockBits' solved my problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM