Size of bitmap byte[] differs from BMP memorystrea

2019-03-03 10:33发布

问题:

I´m trying to send a bitmap over a tcp/ip connection. So far my programm works as it should. But during debugging I discovered a strange value of my bitmap byte[].

I open a 24bit bitmap and convert it to 16bit. The bitmap is 800x600 so the byte[] length should be 800*800*2Byte = 960000Byte... But my array is 960054...

Where do the extra Bytes come from??

        Console.WriteLine("Bitmap auf 16Bit anpassen...\n");
        Rectangle r = new Rectangle(0,0,bitmap_o.Width, bitmap_o.Height);
        Bitmap bitmap_n = bitmap_o.Clone(r, PixelFormat.Format16bppRgb555);
        bitmap_n.Save("test2.bmp");

        Console.WriteLine("Neue Bitmap-Eigenschaften:");
        Console.WriteLine(bitmap_n.Width.ToString());
        Console.WriteLine(bitmap_n.Height.ToString());
        Console.WriteLine(bitmap_n.PixelFormat.ToString());

        byte[] data = new byte[0];
        MemoryStream mem_stream = new MemoryStream();
        bitmap_n.Save(mem_stream, ImageFormat.Bmp);
        data = mem_stream.ToArray();
        mem_stream.Close();

        Console.WriteLine(data.Length.ToString());

        stream.Write(data, 0, 960000);
        Console.WriteLine("Sending data...");

回答1:

The extra bytes is the file header, which contains for example:

  • Bitmap file signature
  • Image dimensions (pixel size)
  • Bit depth
  • Resolution (ppi)

There can also be extra bytes within the pixel data. In your case 800 pixels at two bytes each makes for 1600 bytes per scan line, but if you had for example 145 pixels at three bytes each would make 435 bytes, so a padding byte would be added to each scan line to make it 436 that is evenly divisable by four.

Ref: BMP file format



回答2:

There may be extra bytes in the bitmap array to fill the scan lines to nicer numbers. The effective length of a scan line is called 'Stride' and you test can via the BitmapData.Stride field.

The total length of a Bitmap is calculated like this:

int size1 = bmp1Data.Stride * bmp1Data.Height;

You can have a look at a post, which uses this to create an array for the LockBits method in order to scan a whole Bitmap.