Discussion:
Faulty bitmap writing function?
(too old to reply)
Jack
2009-09-27 06:54:42 UTC
Permalink
typedef struct pixelstruct
{
byte r;
byte g;
byte b;
};

pixelstruct myPixel[500][500]



void SaveData(const char *filename)
{
FILE * f_out;

// save bitmap file headers
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;

fileHeader.bfType = 0x4d42;
fileHeader.bfSize = 0;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) +
sizeof(BITMAPINFOHEADER);

infoHeader.biSize = sizeof(infoHeader);
infoHeader.biWidth = bitmap_dx;
infoHeader.biHeight = bitmap_dy;
infoHeader.biPlanes = 1;
infoHeader.biBitCount = 24;
infoHeader.biCompression = BI_RGB;
infoHeader.biSizeImage = 0;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;

// dibsection information
BITMAPINFO info;
info.bmiHeader = infoHeader;

// ------------------
// THE IMPORTANT CODE
// ------------------
// create a dibsection and blit the window contents to the bitmap
/* HDC winDC = GetWindowDC(window);
HDC memDC = CreateCompatibleDC(hDC);
BYTE* memory = 0;
// turn winDC into bitmap
HBITMAP bitmap = CreateDIBSection(winDC, &info, DIB_RGB_COLORS,
(void**)&memory, 0, 0);
//SetBitmapBits(bitmap, sizeof(byBits), byBits);
// turn bitmap into memDC
SelectObject(memDC, bitmap);
BitBlt(memDC, 0, 0, bitmap_dx, bitmap_dy, winDC, 0, 0, SRCCOPY);
DeleteDC(memDC);
ReleaseDC(window, winDC);

// save dibsection data
int bytes = (((24*bitmap_dx + 31) & (~31))/8)*bitmap_dy;
file.write((const char *)memory,bytes);

// HA HA, forgot paste in the DeleteObject lol, happy now ;)?
//DeleteObject(bitmap);*/

//Write BMP file

RGBQUAD pRGB[256];


for (int q = 0; q < 256; q++) {
pRGB[q].rgbBlue = 0;//0xff;
pRGB[q].rgbGreen = 0;//xff;
pRGB[q].rgbRed = 0;//xff;
pRGB[q].rgbReserved = 0x0;
}

// Open file
if ((f_out = fopen(filename, "wb")) == NULL)
OutputDebugString("Error opening file ");

// Write bmp file header
if (fwrite(&fileHeader, 1, sizeof(BITMAPFILEHEADER), f_out) <
sizeof(BITMAPFILEHEADER)) {
OutputDebugString("Error writing bitmap file header\n");
fclose(f_out); }

// Write bmp info header
if (fwrite(&infoHeader, 1, sizeof(BITMAPINFOHEADER), f_out) <
sizeof(BITMAPINFOHEADER)) {
OutputDebugString("Error writing bitmap info header\n");
fclose(f_out); }


if (fwrite(pRGB,1, sizeof(RGBQUAD)*256, f_out) < (sizeof(RGBQUAD)*256)) {
//if (fwrite(&pRGB,1, sizeof(RGBQUAD), f_out) < (sizeof(RGBQUAD))) {
OutputDebugString("Error writing RGBQUAD\n");
fclose(f_out);
}

//Write BMP data
//memset(myPixel, 0, sizeof(COLORREF)*1000*1000);
for(int i=0; i < bitmap_dy; i++) {
int j = 0;
for(j=0; j < bitmap_dx; j++) { // i and j swapped

fwrite(&myPixel[j][i].r,1,1,f_out);
fwrite(&myPixel[j][i].g,1,1,f_out);
fwrite(&myPixel[j][i].b,1,1,f_out);
}
for(j*=3; j%4!=0; j++) fwrite(&zero,1,1,f_out); // Padding row to 4-byte
multiple!

}
fclose(f_out);
cprintf ("\nFinished Drawing\n");
}

I've cross-checked that myPixel[4][6] for example
is black,RGB(0,0,0), but when that pixel is written to
the file. The position of the black spot has gone to
the lower right of the screen.... can anyone spot
the error of this code snippet? This is a modified version of a cloned
source
Anyway! Thanks for double-checking if you can.
Jack
Jack
2009-09-27 07:01:35 UTC
Permalink
or .. pixelstruct myPixel[500][500];
The question is still open... this typo doesn't
affect the result... this is man-made typo in this post.
Sorry
Jack
Ivan Brugiolo [MSFT]
2009-09-27 07:26:25 UTC
Permalink
It appears that you are expecting a top-down
bitmap while you are saving-it bottom-up.

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by Jack
or .. pixelstruct myPixel[500][500];
The question is still open... this typo doesn't
affect the result... this is man-made typo in this post.
Sorry
Jack
Jack
2009-09-27 07:44:15 UTC
Permalink
Thanks Ivan for your answer!
I just couldn't get it to work no matter how I
changed the code. Could you please give me more tips on this? :).. I'll
appreciate it!
Thanks
Jack
Jack
2009-09-27 11:35:48 UTC
Permalink
http://codereflect.com/2007/03/14/how-to-save-bitmap-to-file/

Finally, it works out with this link...
Thanks Ivan
Jack
Alexander Grigoriev
2009-09-27 13:56:31 UTC
Permalink
The bitmaps are stored in memory and in a file upside down - last scan goes
first.
Post by Jack
typedef struct pixelstruct
{
byte r;
byte g;
byte b;
};
pixelstruct myPixel[500][500]
void SaveData(const char *filename)
{
FILE * f_out;
// save bitmap file headers
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
fileHeader.bfType = 0x4d42;
fileHeader.bfSize = 0;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) +
sizeof(BITMAPINFOHEADER);
infoHeader.biSize = sizeof(infoHeader);
infoHeader.biWidth = bitmap_dx;
infoHeader.biHeight = bitmap_dy;
infoHeader.biPlanes = 1;
infoHeader.biBitCount = 24;
infoHeader.biCompression = BI_RGB;
infoHeader.biSizeImage = 0;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;
// dibsection information
BITMAPINFO info;
info.bmiHeader = infoHeader;
// ------------------
// THE IMPORTANT CODE
// ------------------
// create a dibsection and blit the window contents to the bitmap
/* HDC winDC = GetWindowDC(window);
HDC memDC = CreateCompatibleDC(hDC);
BYTE* memory = 0;
// turn winDC into bitmap
HBITMAP bitmap = CreateDIBSection(winDC, &info, DIB_RGB_COLORS,
(void**)&memory, 0, 0);
//SetBitmapBits(bitmap, sizeof(byBits), byBits);
// turn bitmap into memDC
SelectObject(memDC, bitmap);
BitBlt(memDC, 0, 0, bitmap_dx, bitmap_dy, winDC, 0, 0, SRCCOPY);
DeleteDC(memDC);
ReleaseDC(window, winDC);
// save dibsection data
int bytes = (((24*bitmap_dx + 31) & (~31))/8)*bitmap_dy;
file.write((const char *)memory,bytes);
// HA HA, forgot paste in the DeleteObject lol, happy now ;)?
//DeleteObject(bitmap);*/
//Write BMP file
RGBQUAD pRGB[256];
for (int q = 0; q < 256; q++) {
pRGB[q].rgbBlue = 0;//0xff;
pRGB[q].rgbGreen = 0;//xff;
pRGB[q].rgbRed = 0;//xff;
pRGB[q].rgbReserved = 0x0;
}
// Open file
if ((f_out = fopen(filename, "wb")) == NULL)
OutputDebugString("Error opening file ");
// Write bmp file header
if (fwrite(&fileHeader, 1, sizeof(BITMAPFILEHEADER), f_out) <
sizeof(BITMAPFILEHEADER)) {
OutputDebugString("Error writing bitmap file header\n");
fclose(f_out); }
// Write bmp info header
if (fwrite(&infoHeader, 1, sizeof(BITMAPINFOHEADER), f_out) <
sizeof(BITMAPINFOHEADER)) {
OutputDebugString("Error writing bitmap info header\n");
fclose(f_out); }
if (fwrite(pRGB,1, sizeof(RGBQUAD)*256, f_out) < (sizeof(RGBQUAD)*256)) {
//if (fwrite(&pRGB,1, sizeof(RGBQUAD), f_out) < (sizeof(RGBQUAD))) {
OutputDebugString("Error writing RGBQUAD\n");
fclose(f_out);
}
//Write BMP data
//memset(myPixel, 0, sizeof(COLORREF)*1000*1000);
for(int i=0; i < bitmap_dy; i++) {
int j = 0;
for(j=0; j < bitmap_dx; j++) { // i and j swapped
fwrite(&myPixel[j][i].r,1,1,f_out);
fwrite(&myPixel[j][i].g,1,1,f_out);
fwrite(&myPixel[j][i].b,1,1,f_out);
}
for(j*=3; j%4!=0; j++) fwrite(&zero,1,1,f_out); // Padding row to 4-byte
multiple!
}
fclose(f_out);
cprintf ("\nFinished Drawing\n");
}
I've cross-checked that myPixel[4][6] for example
is black,RGB(0,0,0), but when that pixel is written to
the file. The position of the black spot has gone to
the lower right of the screen.... can anyone spot
the error of this code snippet? This is a modified version of a cloned
source
Anyway! Thanks for double-checking if you can.
Jack
Loading...