Can someone explain me how this device-context madness of Windows bitmaps works? it seems the MicroSoft doc I can dig up on this is just plain wrong.
What I want s very simple: I have a program that just prepared a bitmap, and copied it to the screen using BitBlt. Now I want to write that same bitmap to a file. One would expect there to be a standard call for that, as this does not seem such an outlandish action. But I could not find it.
The bitmap that was copied to the screen is only known to the program as a handle: HBITMAP bufferBitmap;
I got as far as using GetObject(bufferBitmap, sizeof(bm), &bm), where bm was declared as BITMAP, to dereference the handle pointer. (Can anyone explain me why simply writing *bufferBitmap does not work?)
The BITMAP structure that is written to bm by this call seems OK, in the sense that the bmWidth and bmHeight fields do indeed react to, and reflect the size of the image to be saved correctly. But according to the specs that structure should also contain a pointer to the actual bitmap pixels. But tht pointer is NULL.
How can Windows copy the image to the screen if it does not know eher the data is. Is this just a quirk of GetObject, that it tries to hide the data from th programmer to prevent tht it is useful? How does windows get to the data to be copied in a BitBlt? The BitBlt does not even get the bitmap to be copied as an argument, the only hint to what it must do is passed to it as a device context handle (HDC). Apparently this gets associated with a bitmap by a call to SelectObject. How would I get to the data starting from this handle, using only plain C pointer dereferencing in stead of calls to malignant functions? Or is this not possible at all, because the data is hidden in kernel memory space that a usere cannor access?
Writing out a bitmap
Moderator: Ras
-
- Posts: 28355
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
-
- Posts: 373
- Joined: Wed Mar 22, 2006 10:17 am
- Location: Novi Sad, Serbia
- Full name: Karlo Balla
Re: Writing out a bitmap
Working with windows bitmap without wrapper is painful task especially if you don't have experience with them. Maybe you should consult MSDN.
http://msdn.microsoft.com/en-us/library ... S.85).aspx
Good Luck!!!
http://msdn.microsoft.com/en-us/library ... S.85).aspx
Good Luck!!!
Best Regards,
Karlo Balla Jr.
Karlo Balla Jr.
Re: Writing out a bitmap
I think you must use a DIB (not a ddb).
http://www.codeproject.com/KB/graphics/DFB_vs_DIB.aspx
http://www.programmersheaven.com/mb/win ... ssage.aspx
http://www.matthiaspospiech.de/blog/200 ... d-bitmaps/
HJ.
http://www.codeproject.com/KB/graphics/DFB_vs_DIB.aspx
http://www.programmersheaven.com/mb/win ... ssage.aspx
http://www.matthiaspospiech.de/blog/200 ... d-bitmaps/
HJ.
-
- Posts: 2251
- Joined: Wed Mar 08, 2006 8:47 pm
- Location: Hattingen, Germany
Re: Writing out a bitmap
Native Windows API is horror. Usually a Device Context is associated with a window or printer device.hgm wrote:Can someone explain me how this device-context madness of Windows bitmaps works? it seems the MicroSoft doc I can dig up on this is just plain wrong.
What I want s very simple: I have a program that just prepared a bitmap, and copied it to the screen using BitBlt. Now I want to write that same bitmap to a file. One would expect there to be a standard call for that, as this does not seem such an outlandish action. But I could not find it.
The bitmap that was copied to the screen is only known to the program as a handle: HBITMAP bufferBitmap;
I got as far as using GetObject(bufferBitmap, sizeof(bm), &bm), where bm was declared as BITMAP, to dereference the handle pointer. (Can anyone explain me why simply writing *bufferBitmap does not work?)
The BITMAP structure that is written to bm by this call seems OK, in the sense that the bmWidth and bmHeight fields do indeed react to, and reflect the size of the image to be saved correctly. But according to the specs that structure should also contain a pointer to the actual bitmap pixels. But tht pointer is NULL.
How can Windows copy the image to the screen if it does not know eher the data is. Is this just a quirk of GetObject, that it tries to hide the data from th programmer to prevent tht it is useful? How does windows get to the data to be copied in a BitBlt? The BitBlt does not even get the bitmap to be copied as an argument, the only hint to what it must do is passed to it as a device context handle (HDC). Apparently this gets associated with a bitmap by a call to SelectObject. How would I get to the data starting from this handle, using only plain C pointer dereferencing in stead of calls to malignant functions? Or is this not possible at all, because the data is hidden in kernel memory space that a usere cannor access?
If your windows-callback routine (assigned by RegisterWindowClass) receives a WM_PAINT message, one uses BeginPaint to get the DeviceContext, applies some drawing or TextOut methods with this DC and EndPaint to release it. Otherwise, if not processing WM_PAINT, you can use HDC GetDC(HWND hWnd) for a window device context or CreateDC/DeleteDC for other devices.
According to GetObject from MSDN:
In Win32 a handle is likely an "encapsulated" void*. There were/are issues with windows memory API even from 16-bit windows, related to getting a handle of a piece of "movable" allocated memory by LocalAlloc or GlobalAlloc, where LocalLock or GlobalLock receives the pointer and "Locks" the memory so that it is no longer "movable".if hgdiobj is a handle to a bitmap created by any other means, GetObject returns only the width, height, and color format information of the bitmap. You can obtain the bitmap's bit values by calling the GetDIBits or GetBitmapBits function.
-
- Posts: 28355
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Writing out a bitmap
OK, thanks for the pointers. Indeed I have found something that works, using GetDIBits. Don't ask me why: I got it from a Chinese site where the C-code was the only thing that was displayed in western characters.
Apparently it can copy the bitmap data to a user-declared array of bytes, and from there I can write it. Funny enough it seems to appear in that buffer upside down: if I want to delete the top part of the bitmap I have to refrain from writing the end of the array to file!
Anyway, I can write the WinBoard display as a diagram to a file, which other Windows software (like Paint) understands ithout complaints. Only thing is that this file is rather large, as it uses 32 bites per pixel. I guess for a Chess diagram 4 bits per pixel would be more than enough, so I should do a little processing on the bitmap before writing it to file.

Anyway, I can write the WinBoard display as a diagram to a file, which other Windows software (like Paint) understands ithout complaints. Only thing is that this file is rather large, as it uses 32 bites per pixel. I guess for a Chess diagram 4 bits per pixel would be more than enough, so I should do a little processing on the bitmap before writing it to file.
Re: Writing out a bitmap
Bitmaps are stored in a file upside down. From the wikipage (that I know to be accurate "enough" because I implemented something from it in the past):
Bitmap data
This block of bytes describes the image, pixel by pixel. Pixels are stored "upside-down" with respect to normal image raster scan order, starting in the lower left corner, going from left to right, and then row by row from the bottom to the top of the image.[2]
Uncompressed Windows bitmaps can also be stored from the top row to the bottom, if the image height value is negative. If the number of bytes matching a row (scanline) in the image is not divisible by 4, the line is padded with one to three additional bytes of unspecified value so that the next row will start on a multiple of 4 byte location in memory or in the file. Following these rules there are several ways to store the pixel data depending on the color depth and the compression type of the bitmap.
http://en.wikipedia.org/wiki/Windows_bitmap
I hate bitmaps - no wonder base Java still refuses to support them
Andy.
Bitmap data
This block of bytes describes the image, pixel by pixel. Pixels are stored "upside-down" with respect to normal image raster scan order, starting in the lower left corner, going from left to right, and then row by row from the bottom to the top of the image.[2]
Uncompressed Windows bitmaps can also be stored from the top row to the bottom, if the image height value is negative. If the number of bytes matching a row (scanline) in the image is not divisible by 4, the line is padded with one to three additional bytes of unspecified value so that the next row will start on a multiple of 4 byte location in memory or in the file. Following these rules there are several ways to store the pixel data depending on the color depth and the compression type of the bitmap.
http://en.wikipedia.org/wiki/Windows_bitmap
I hate bitmaps - no wonder base Java still refuses to support them

Andy.
-
- Posts: 28355
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Writing out a bitmap
OK, I succeded in having the bitmap written in a somewhat more manageble format (4 bits/pixel, in stead of 32):
http://home.hccnet.nl/h.g.muller/diagram.bmp
(Apparently bmp files are not valid image type on this forum, so you will have to click the link.)
It is still a bit big (105 kB), though, since the bitmap is uncompressed, and the picture of course is imminently suitable for something like run-length coding.
When I try to convert it to a smarter format, like GIF, it shrinks to 21 kB. But then I get a very ugly effect on the square colors, though:

Someone once told me that this is because the GIF format tries to approximate the original color with a much smaller pallette, using dither. Rather stupid, since the entire picture contains only 5 colors, and a color table describing these colors from a 4-billion-color palette would only cost 20 bytes.
Is there anything I can do about this, e.g. by picking the starting colors a bit smarter (i.e. have WinBoard 'round' them to colors in the GIF pallette, while rendering the diagram)? Is it know which colors can be used in GIF files without getting the dither, or is this a matter of trying out all 16 million colors?
http://home.hccnet.nl/h.g.muller/diagram.bmp
(Apparently bmp files are not valid image type on this forum, so you will have to click the link.)
It is still a bit big (105 kB), though, since the bitmap is uncompressed, and the picture of course is imminently suitable for something like run-length coding.
When I try to convert it to a smarter format, like GIF, it shrinks to 21 kB. But then I get a very ugly effect on the square colors, though:
Someone once told me that this is because the GIF format tries to approximate the original color with a much smaller pallette, using dither. Rather stupid, since the entire picture contains only 5 colors, and a color table describing these colors from a 4-billion-color palette would only cost 20 bytes.
Is there anything I can do about this, e.g. by picking the starting colors a bit smarter (i.e. have WinBoard 'round' them to colors in the GIF pallette, while rendering the diagram)? Is it know which colors can be used in GIF files without getting the dither, or is this a matter of trying out all 16 million colors?
-
- Posts: 2179
- Joined: Fri Jul 14, 2006 7:56 am
- Location: London, England
- Full name: Jim Ablett
Re: Writing out a bitmap
Hi Harm,
I download your bmp and converted to gif using free Irfanview viewer/converter. http://www.irfanview.com/
Shrunk to 11.8kb.

Jim.
I download your bmp and converted to gif using free Irfanview viewer/converter. http://www.irfanview.com/
Shrunk to 11.8kb.

Jim.
-
- Posts: 2851
- Joined: Wed Mar 08, 2006 10:01 pm
- Location: Irvine, CA, USA
Re: Writing out a bitmap
I don't think that should happen. I tried converting the .bmp file to a .gif file using IrfanView and it came out looking fine, and smaller than your .gif too.hgm wrote:When I try to convert it to a smarter format, like GIF, it shrinks to 21 kB. But then I get a very ugly effect on the square colors, though:
![]()
[Edit: I'm too slow! Incidentally, writing it as a .png would make it smaller still, and it's lossless.]
-
- Posts: 28355
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Writing out a bitmap
OK, so it is just this lousy MicroSoft Paint, and I hould not worry about it. 
