6

I have a ByteArray from a camera,it's just a stream and has no bitmapheader.

I have searched for a demo,but they are all in C++.

I try to add a bitmapheader to my code, but a ParameterException is thrown. How do I make a bitmap file from the ByteArray?

1

5 Answers 5

11

You can't make a bitmap class directly with a raw data that doesn't have the bitmap header. The bitmap header is like a recipe for a bitmap image. It includes the essential information about width, height, bit per pixels, length of the data, and etc in order to make a proper array for the image.

Making the bitmap header is fairly easy if you take a close look at the bitmap header structure here


But nothing is better than a complete example of a source code.

I broke them down into some pieces and commented on the each steps for you throughout the whole process. It probably looks a bit excessive and verbose, but it's going to be a good guide for you I guess.


Following is an example of a 2×2 pixel, 24-bit bitmap (Windows DIB header BITMAPINFOHEADER) with pixel format RGB24.

BMP file format - Wikipedia

#region Bitmap Making...

// BmpBufferSize : a pure length of raw bitmap data without the header.
// the 54 value here is the length of bitmap header.
byte[] BitmapBytes = new byte[BmpBufferSize + 54];

#region Bitmap Header
// 0~2 "BM"
BitmapBytes[0] = 0x42;
BitmapBytes[1] = 0x4d;

// 2~6 Size of the BMP file - Bit cound + Header 54
Array.Copy(BitConverter.GetBytes(BmpBufferSize + 54), 0, BitmapBytes, 2, 4);

// 6~8 Application Specific : normally, set zero
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 6, 2);

// 8~10 Application Specific : normally, set zero
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 8, 2);

// 10~14 Offset where the pixel array can be found - 24bit bitmap data always starts at 54 offset.
Array.Copy(BitConverter.GetBytes(54), 0, BitmapBytes, 10, 4);
#endregion

#region DIB Header
// 14~18 Number of bytes in the DIB header. 40 bytes constant.
Array.Copy(BitConverter.GetBytes(40), 0, BitmapBytes, 14, 4);
                    
// 18~22 Width of the bitmap.
Array.Copy(BitConverter.GetBytes(image.Width), 0, BitmapBytes, 18, 4);

// 22~26 Height of the bitmap.
Array.Copy(BitConverter.GetBytes(image.Height), 0, BitmapBytes, 22, 4);

// 26~28 Number of color planes being used
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 26, 2);

// 28~30 Number of bits. If you don't know the pixel format, trying to calculate it with the quality of the video/image source.
if (image.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
{                        
    Array.Copy(BitConverter.GetBytes(24), 0, BitmapBytes, 28, 2);
}

// 30~34 BI_RGB no pixel array compression used : most of the time, just set zero if it is raw data.
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 30, 4);

// 34~38 Size of the raw bitmap data ( including padding )
Array.Copy(BitConverter.GetBytes(BmpBufferSize), 0, BitmapBytes, 34, 4);

// 38~46 Print resolution of the image, 72 DPI x 39.3701 inches per meter yields
if (image.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
{
    Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 38, 4);
    Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 42, 4);
}

// 46~50 Number of colors in the palette
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 46, 4);

// 50~54 means all colors are important
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 50, 4);

// 54~end : Pixel Data : Finally, time to combine your raw data, BmpBuffer in this code, with a bitmap header you've just created.
Array.Copy(BmpBuffer as Array, 0, BitmapBytes, 54, BmpBufferSize);

#endregion - bitmap header process
#endregion - bitmap making process
Sign up to request clarification or add additional context in comments.

1 Comment

I still wonder why there is no framework builtin for this.
0

Use the System.Drawing.Bitmap class

Comments

-1

Maybe this is what you're looking for ...

http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/e57f7731-c703-4c17-b1a2-32b155f9b745/

Comments

-1

Checkout these links:

Comments

-1

This will work

...

using System;
using System.IO;
using System.Drawing;

...

public Image ByteArrayToImage(byte[] byteArrayIn)
{

 MemoryStream ms = new MemoryStream(byteArrayIn);
                   Image img = Image.FromStream(ms);
                   return img;
}

2 Comments

This question exists because the code you provided does cause an error in some (many) cases.
@beppe9000 How exactly? Can you post the error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.