Solved

create a bmp header at byte level

Posted on 2004-04-28
9
462 Views
Last Modified: 2012-06-21
hi,
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
stream.Close();

return bmp;
}

Thanks for the help!
0
Comment
Question by:NGDESL
  • 4
  • 3
9 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 10945812
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.
0
 

Author Comment

by:NGDESL
ID: 10948989
bump, with point increase.  Need some help, even if it's just pointing me in the right direction.
0
 

Author Comment

by:NGDESL
ID: 10950465
sorry, i'm not to familiar with this.  Are there any code examples i can look at?
0
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 48

Expert Comment

by:AlexFM
ID: 10951380
Can you describe format of this image? What is "raw dib"?
0
 

Author Comment

by:NGDESL
ID: 10951822
The image has the BITMAPINFOHEADER data already incorporated into it.  BITMAPINFOHEADER  is the following:

private class BITMAPINFOHEADER
               {
                    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:

private class BITMAPFILEHEADER
               {
                    [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
0
 

Author Comment

by:NGDESL
ID: 10954143
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.
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
ID: 10958096
Bitmap file has the following structure:

1) BITMAPFILEHEADER 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.
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Najam
Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

774 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question