Solved

create a bmp header at byte level

Posted on 2004-04-28
9
468 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

Question has a verified solution.

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

Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Come and listen to Percona CEO Peter Zaitsev discuss what’s new in Percona open source software, including Percona Server for MySQL (https://www.percona.com/software/mysql-database/percona-server) and MongoDB (https://www.percona.com/software/mongo-…
If you're a developer or IT admin, you’re probably tasked with managing multiple websites, servers, applications, and levels of security on a daily basis. While this can be extremely time consuming, it can also be frustrating when systems aren't wor…

688 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