|
-
September 3rd, 2004, 04:10 PM
#1
Question for Bitmap Decoding
Hi, I am trying to get the pixel info from a bitmap file but encountered some difficulties. The ones that I am trying is a monochrome (biBitCount == 1) and their header info are as follows:
Test File ----------- (1) ----------- (2) --------- (3) ---------- (4) --------- (5) -------- (6)
info got from bitmap header:
bmWidth ---------- 84 ---------- 168 -------- 252 --------- 335 -------- 419 ------- 586
bmHeight -------- 606 -------- 1211 ------ 1817 -------- 2422 ------- 3028 ----- 4239
bmWidthBytes --- 12 ----------- 24 ---------- 32 ----------- 44 ---------- 56 -------- 76
==========================================================
# bytes to get --- 12 ----------- 22 ---------- 32 ----------- 42 ---------- 54 ------- 74
I know that Each line in the array of data for the bitmap must be LONG aligned (divisible by 4 bytes).
Since I was decoding row by row, if taking the number of bytes specified as "bmWidthBytes" in the header for the entire row, and encoded the bit of each byte for the pixels (1 => white, 0 => black), only test file (1) and (3) got the image right, others would get a skewed result and some info missing at the bottom of image. This makes me think more bytes have been taken than necessary, which belong to the next row of image.
If taking the number of bytes as "# bytes to get", then everything was OK. I got these with trial and error!
Does any one see what is wrong and how to figure out the right number of bytes to take for the entire row? Thanks for any help in advance.
Raymond
Last edited by rayq; September 7th, 2004 at 11:38 AM.
-
September 3rd, 2004, 06:04 PM
#2
Re: Question for Bitmap Decoding
The bmWidthBytes values are the correct.
I think the problem is in your processing code.
-
September 3rd, 2004, 09:17 PM
#3
Re: Question for Bitmap Decoding
Originally quoted by rayq
I know that Each line in the array of data for the bitmap must be LONG aligned (divisible by 32).
The number of bytes in each line in the bitmap must be evenly divisible by 4, if it isn't windows will pad the the line with either 1, 2 or 3 bytes to make it evenly divisible by 4.
In the bitmap file header, the width is bytes 18 through 21 and the height is bytes 22 through 25. You have to take the bytes and create an unsigned long value to get the numbers. This can be done easily with the MAKEWORD and MAKELONG macros. The total size of the header is 54 bytes.
One final note, the first line in the bitmap is the last line in the file.
Hope that helps
Last edited by TDM; September 3rd, 2004 at 09:19 PM.
-
September 7th, 2004, 11:05 AM
#4
Re: Question for Bitmap Decoding
Thanks for your replies!
I don't see (or can't see) anything wrong with my code . below is what I wrote to deal with monochrome bitmap:
{:
CBitmap bitmap;
bitmap.Attach(hBmp);
// get info from bitmap file hdr.DIBSECTION ds;
bitmap.GetObject(sizeof(ds), &ds);
int width = ds.dsBmih.biWidth;
int height = ds.dsBmih.biHeight;
long imgSiz = ds.dsBmih.biSizeImage;
BYTE *bmBits = new BYTE[imgSiz]; // To store bitmap pixels. // get bm bits from bitmap.
bitmap->GetBitmapBits(imgSiz, bmBits);
// to store indices to cgm color table
USHORT *cellarray = new USHORT[width * height];
int numwidthbytes = ds.dsBm.bmWidthBytes;
// to store pixels of whole row
BYTE *widthbyte = new BYTE[numwidthbytes];
int row, col, cntr;
for (row = 0, cntr = 0; row < height; row++)
{
// copy entire row bytes
memcpy(widthbyte, &bmBits[row * 22], 22); // ***
for (col = 0; col < width; col++)
cellarray[cntr++] = set_Pixels(widthbyte[col / 8], col); }
:
:
delete [] widthbyte;
delete [] cellarray;
delete [] bmBits; }
// Decode bit info for exported pixel
USHORT CgsCGMFile::set_Pixels(const BYTE bmbyte, const int col)
{
int bitpos = (col + 1) % 8;
USHORT pixel = 0; // set to black
switch (bitpos) // order from left to right
{
case 1: // 1xxx xxxx
if (bmbyte & 0x80) pixel = 1; // set to white
break;
case 2: // x1xx xxxx
if (bmbyte & 0x40) pixel = 1; // set to white break; case 3: // xx1x xxxx if (bmbyte & 0x20) pixel = 1; // set to white break; case 4: // xxx1 xxxx if (bmbyte & 0x10) pixel = 1; // set to white break; case 5: // xxxx 1xxx if (bmbyte & 0x08) pixel = 1; // set to white break; case 6: // xxxx x1xx if (bmbyte & 0x04) pixel = 1; // set to white break; case 7: // xxxx xx1x if (bmbyte & 0x02) pixel = 1; // set to white break; case 0: // xxxx xxx1 if (bmbyte & 0x01) pixel = 1; // set to white break; default: break; }
return pixel;
}
What I am working on is to convert bitmap to CGM format with cgmcell_array(). The array "cellarray" is to store pixel information for use in "cgmcell_array" function. The problem happened in the line (with comment // ***) inside the for loop. Note that I used "22" (for test (2)) not "numwidthbytes" (= ds.dsBm.bmWidthBytes) or "24" to get the correct result.
Thanks for any help in advance.
Raymond
Last edited by rayq; September 7th, 2004 at 11:50 AM.
-
September 16th, 2004, 03:20 PM
#5
Any Help??? (NT)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|