Solved

create a bmp header at byte level

Posted on 2004-04-28
9
456 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
Comment Utility
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
Comment Utility
bump, with point increase.  Need some help, even if it's just pointing me in the right direction.
0
 

Author Comment

by:NGDESL
Comment Utility
sorry, i'm not to familiar with this.  Are there any code examples i can look at?
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 48

Expert Comment

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

Author Comment

by:NGDESL
Comment Utility
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
Comment Utility
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
Comment Utility
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

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Suggested Solutions

Introduction                                                 Was the var keyword really only brought out to shorten your syntax? Or have the VB language guys got their way in C#? What type of variable is it? All will be revealed.   Also called…
Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
This video discusses moving either the default database or any database to a new volume.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

772 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now