• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 477
  • Last Modified:

create a bmp header at byte level

I'm relateively new to C# and very new to it's byte and stream methods so this task is beyond me.
What I'm trying to do is read image information out of a sql DB stored as byte data.  The image information is raw dib.  I'd like to convert this to bmp and post it to a form image box so i need at add bmp header information to it.  This is where I'm lost.  I've done this is PHP but I don't know how to convert it to C#.  Here's the PHP code:

$info = unpack("lwidth/lhight/Splanes/Sbitcount/Lcompression/Lsizeimage/lxpelspermeter/lypelspermeter/Lclrused/lclrimportant",$av_image);
$offset = 54 + ($info['clrused'] * 4);
$header = pack("cclssL", ord('B'), ord('M'), strlen($av_image)+14, 0, 0, $offset, 40); // type(2), size, reserved, reserved, offset, header_size

So basically what I am doing is extracting the "clrused" value (unsigned long, 4 bytes) information from the dib and using the value to create "offset".  Then creating the header (char, char, long, short shot, long).

This header is then added to a memory stream followed by the dib data.

This is what I have so far, but it's a mess and no where near complete:

byte[] data = (byte[])myCommand.ExecuteScalar();
MessageBox.Show(Convert.ToString(data.Length), "Database");
if(data.Length > 0)
// Open a stream for the image and write the bytes into it
System.IO.MemoryStream stream = new System.IO.MemoryStream(data, true);
stream.Write(data, 0, data.Length);

byte[] clrused = new byte[4];
stream.Read(clrused, 28, 4);
int offset = 54 + (Convert.ToInt32(clrused) * 4);
//stream.Write(data, 0, data.Length);
// Create a bitmap from the stream
Bitmap bmp = new Bitmap(stream);

// Close the stream

return bmp;

Thanks for the help!
  • 4
  • 3
1 Solution
If this information is raw dib, possibly bitmap header is kept in the BITMAPINFO structure. In this case you can create such bitmap using CreateDIBSection API and fill it's bits using SetBitmapBits function. After this you can create Bitmap from HBITMAP.
NGDESLAuthor Commented:
bump, with point increase.  Need some help, even if it's just pointing me in the right direction.
NGDESLAuthor Commented:
sorry, i'm not to familiar with this.  Are there any code examples i can look at?
7 new features that'll make your work life better

It’s our mission to create a product that solves the huge challenges you face at work every day. In case you missed it, here are 7 delightful things we've added recently to monday to make it even more awesome.

Can you describe format of this image? What is "raw dib"?
NGDESLAuthor Commented:
The image has the BITMAPINFOHEADER data already incorporated into it.  BITMAPINFOHEADER  is the following:

                    public int          biSize;
                    public int          biWidth;
                    public int          biHeight;
                    public short     biPlanes;
                    public short     biBitCount;
                    public int          biCompression;
                    public int          biSizeImage;
                    public int          biXPelsPerMeter;
                    public int          biYPelsPerMeter;
                    public int          biClrUsed;
                    public int          biClrImportant;

Basically, I'm just trying to add the BITMAPFILEHEADER information to the beginning of the byte stream:

                    [MarshalAs( UnmanagedType.ByValArray, SizeConst=2)]
                    public Char[]     Type;
                    public Int32     Size;
                    public Int16     reserved1;
                    public Int16     reserved2;
                    public Int32     OffBits;

I don't think this is very complicated, but I haven't delt with byte data in C# so I'm not really sure how to go about this.  Is BITMAPFILEHEADER a known struct type or do you have to declare it?  Thanks
NGDESLAuthor Commented:
Here's what I have come up with:

byte[] data = (byte[])myCommand.ExecuteScalar();
System.IO.MemoryStream stream = new System.IO.MemoryStream(data.Length);
int offset = 54 + (BitConverter.ToInt32(data, 28) * 4);
stream.Write(BitConverter.GetBytes('B'), 0, BitConverter.GetBytes('B').Length);
stream.Write(BitConverter.GetBytes('M'), 0, BitConverter.GetBytes('M').Length);
stream.Write(BitConverter.GetBytes(data.Length+14), 0, BitConverter.GetBytes(data.Length+14).Length);
stream.Write(BitConverter.GetBytes(0), 0, 4);
stream.Write(BitConverter.GetBytes(0), 0, 4);
stream.Write(BitConverter.GetBytes(offset), 0, 4);
stream.Write(BitConverter.GetBytes(40), 0, 4);
stream.Write(data, 0, data.Length);
Bitmap bmp = new Bitmap(stream);

it throws an ArgumentException every time on the "Bitmap bmp = new Bitmap(stream);" line and i have no idea why.
Bitmap file has the following structure:

Type is BM
bfSize is whole bitmap file size - you need to count it
bfOffBits is offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits - you need to count it.

2) BITMAPINFO structure which contains:

BITMAPINFOHEADER structure - this is what you already have
RGBQUAD structure - 4 bytes.

If bitmap has color palette, palette members are placed immidiately after BITMAPINFO structure. For example, if bitmap has 256-colors palette, additional 255 RGBQUAD structures are placed after BITMAPINFO (BITMAPINFO contains one structure). If bitmap doesn't contain palette, BITMAPINFO still contails one RGBQUAD member (not used).

3) Bitmap bits which are placed immidialely after color palette or BITMAPINFO structure.

Your stream contains BITMAPINFOHEADER structure. Nice, does it contain also color palette and bitmap bits? Assuming that it contains all this exactly as in bitmap file, all you need is to add BITMAPFILEHEADER to the beginning and count it's bfSize and bfOffBits members. Possibly bfSize is equal to stream size + sizeof(BITMAPINFOHEADER). To count bfOffBits, you need to use BITMAPINFOHEADER.biClrUsed member. Read it's description in MSDN.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now