...

View Full Version : writing a bitmap file



ahLi
03-08-2004, 07:29 AM
hi. i tried to output a bitmap file but it seems to be invalid and hence, i can't open it.

I've assigned values to the BITMAPINFOHEADER and colour table. Using WriteFile method, I wrote the above BITMAPINFO into a bitmap file.

The raw pixel image is in a char array:
unsigned char ByteImage [200*152];

Do you know how to write the data in this ByteImage into the bitmap data part of the bitmap file?

I tried something like:
WriteFile(hFile, ByteImage, sizeof(ByteImage), &dwBytesWritten, NULL);

the bitmap file is created but it can't be opened for viewing, saying that the file is not a valid bitmap format. anybody knows what went wrong?

thanks alot

sad69
03-09-2004, 01:17 AM
I don't know what you're talking about!

You'll have to explain what language, platform, etc.. that you're working with.

Sadiq.

ahLi
03-09-2004, 03:15 AM
I'm using C++ language and working on Windows NT platform.

I'm trying to create a bitmap file. I've already initialised the properties needed in the BITMAPINFO structure.

For example,
m_DIB->bmiHeader.biWidth = 152;
m_DIB->bmiHeader.biHeight = 200;
etc...

Next, I need to write this BITMAPINFO structure into a .bmp file.

WriteFile(hFile, m_DIB, sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD), &dwBytesWritten, NULL);

Now, I need to read the bitmap data into the .bmp file.

unsigned char ByteImage [200*152];
memcpy(ByteImage,birData->BiometricData+24,152*200);
dwBytesToWrite = sizeof(ByteImage);
WriteFile(hFile, ByteImage, dwBytesToWrite, &dwBytesWritten, NULL);

After doing this, the .bmp file is created. However, when I want to open and view it, this error message appears:
"Paint cannot read this file. This is not a valid bitmap file, or its format is not currently supported"

Do you have any idea what went wrong?

Mhtml
03-10-2004, 09:12 AM
Why are you using a char array?? You should be using a BYTE array. I don't know if this will make a difference but it might.

I think .bmp should also be written as BGR not RGB so you'll have to swap every 3rd byte with byte[n-2] ...

It's a little hard to see the whole problem without seeing a little more code though.

Mhtml
03-10-2004, 09:19 AM
And the size of the array should be width*height*depth.

ahLi
03-12-2004, 03:44 AM
I've managed to output a valid bitmap file now but its the image is distorted...

What do you mean by swaping every 3rd byte with [n-2]byte?
How do I actually go about doing that?

Mhtml
03-13-2004, 12:15 PM
Well, you need to do a loop to swap every 3rd byte with the one 2 bytes before it. Which will convert it from RGB to BGR.

Like --



BYTE tmp;
for ( int i = 3; i < array_size; i+=3 ) {

tmp = bmp[i-2];
bmp[i-2] = bmp[i];
bmp[i] = tmp;

}


Or you can use memmove()...

I'm really sick right now so my thinking may be a little off, hopefully that code is actually right ;):)..


[edit:] Assuming I'm actually right ( are the colors wrong on the bitmap? Inverted? ) ...

Each pixel has a color index right, each color is an RGB value.

Bitmaps should be in the BGR format I think, at least I remember when I wrote a bitmap loader for opengl textures that it had to be transformed from BGR to RGB to use it. Which is why I believe it needs to be save in BGR...

Anyways, the BYTE array is really just and array of colors. .. So for example -

BYTE[0] = Red value
BYTE[1] = Green value
BYTE[2] = Blue value

RGB!

But, assuming my memory serves me correctly and you need to swap these bytes every set of 3 in the array would be in the format BGR

BYTE[0] = Blue value
BYTE[1] = Green value
BYTE[2] = Red value

And it just repeats like that, with BYTE[3] being blue value and BYTE[5] being red value and so on..

I hope I haven't confused you. :) This better be right or I'll look like a fool.. :D

Mhtml
03-13-2004, 12:27 PM
Post your code if you still have some problems. :)

ahLi
03-16-2004, 06:38 AM
I'm trying to create a 24bit uncompressed bitmap file. the following codes gave me distorted bitmap image and appears to have 4 distinct sections.


// Put image data in ByteImage
memcpy(ByteImage,birData-> BiometricData + 24, 152*200);

// Bitmap file header
BITMAPFILEHEADER *m_header = (BITMAPFILEHEADER *) malloc(sizeof(BITMAPFILEHEADER));
m_header->bfType = 'MB';
m_header->bfSize = 0;
m_header->bfReserved1 = 0;
m_header->bfReserved2 = 0;
m_header->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

// Bitmap infoheader
BITMAPINFOHEADER *m_DIB = (BITMAPINFOHEADER *) malloc(sizeof(BITMAPINFOHEADER));
m_DIB->biSize = sizeof (BITMAPINFOHEADER);
m_DIB->biWidth = 152;
m_DIB->biHeight = 200;
m_DIB->biPlanes = 1;
m_DIB->biBitCount = 24;
m_DIB->biCompression = BI_RGB; m_DIB->biSizeImage = 152*200*3;
m_DIB->biXPelsPerMeter = 0;
m_DIB->biYPelsPerMeter = 0;
m_DIB->biClrUsed = 0;
m_DIB->biClrImportant = 0;

unsigned char tmp;
for (int j = 3; j < 152*200*3; j+=3)
{
tmp = ByteImage[j-2];
ByteImage[j-2] = ByteImage[j];
ByteImage[j] = tmp;
}

// Open the file
wsprintf(szFileName, TEXT("c:\\Templates\\%s.bmp"), lptszUserName);
hFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return(0);

// Write BITMAPFILEHEADER
WriteFile(hFile, m_header, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);

// Write BITMAPINFOHEADER
WriteFile(hFile, m_DIB, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);

// Write bitmap data
WriteFile(hFile, ByteImage, sizeof(ByteImage), &dwBytesWritten, NULL);

// Close the file
CloseHandle(hFile);


I've read that behind each scan line there's some "junk bytes" appended to it. Could it be that these "junk bytes" that caused the distorted image?

s.basu9
01-02-2007, 10:49 AM
Yes the distortion is just bcoz of junk bytes. You have to take care of junk bytes while reading or writting a 24-bit bitmap image. Since in each scan line the number of bytes should b multiple of 4, there may be some extra bytes. At the time of reading u must jump over those bytes in each scan line. And while creating a 24-bit bitmap u've to write the junk bytes into the output file.
To find out junk bytes in each scan line u can try the following line of code in c :--
int junkBytes=(fileSize - (imageSize*3 + 54)/width) / height;
where fileSize = total disk size of the file
imageSize = width * height;
another thing u must notice --- in ur code u've written "MB" as BMP identifier, but it should be "BM".



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum