0

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...");
TaW
  • 53,122
  • 8
  • 69
  • 111
royalTS
  • 603
  • 4
  • 22
  • If you look at the BITMAP file format it is clear that you should not count only the pixels http://en.wikipedia.org/wiki/BMP_file_format – Steve Jul 06 '14 at 12:40
  • 1
    @Steve you should post this as an answer. – Stilgar Jul 06 '14 at 12:42
  • 2
    Just nitpicking: The instantiation of the empty byte array `byte[] data = new byte[0];` is superfluous. (Well, it does not have a negative side effect, but it also does not have any benefit...). Get rid of it and just do `byte[] data;`. Also don't use streams + stream.Close() but rather `using (MemoryStream mem_stream = ...) { ...do stuff with stream... }` -- the *using* statement ensures that the stream is being closed in timely fashion when the *using* block is being left... –  Jul 06 '14 at 13:08
  • There is nitpicking and then there is good advice. +1 for being on the right side – TaW Jul 06 '14 at 13:14

2 Answers2

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.

Community
  • 1
  • 1
TaW
  • 53,122
  • 8
  • 69
  • 111
  • Whoops, I thought you were talking about an expected data size vs the actual size of a bitmap in memory. I'll leave this answer, even though it is not to your question, as is contains some useful information as well. As for the filesize Steve got it right; even a dumb format like BMP has a small header. – TaW Jul 06 '14 at 12:55
2

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

Guffa
  • 687,336
  • 108
  • 737
  • 1,005