Create DIB from a HBITMAP
-
I have a handle to bitmap. I need to store this bitmap to a xml file. The xml file will be read on a mac system. So how do I create a DIB from a HBITMAP? Thanks..
Creating a DIB section from a BMP file[^].
Of one Essence is the human race thus has Creation put the base One Limb impacted is sufficient For all Others to feel the Mace (Saadi )
-
Creating a DIB section from a BMP file[^].
Of one Essence is the human race thus has Creation put the base One Limb impacted is sufficient For all Others to feel the Mace (Saadi )
-
That is not what I require. Not from a file. I already have a HBITMAP from the file. I need a logic that converts a HBITMAP to a DIB, which will be readable on a mac system.
1. Get dimensions of existing HBITMAP 2. Use CreateDIBSection to create an image of the correct size 3. Create a couple of memory DCs 4. Select the images into their own DCs 5. BitBlt from the DC holding the HBITMAP to the one containing the DIBSection 6. Save the DIBSection to disk (you can use the supplied function) 7. Deselect the images from their DCs 8. DeleteObject both images (HBITMAP & DIBSection)
BOOL SaveBitmapFile(HDC p_hDC, LPCTSTR p_pchFileName)
{
HBITMAP hBmp = (HBITMAP)GetCurrentObject( p_hDC, OBJ_BITMAP );BITMAPINFO stBmpInfo; stBmpInfo.bmiHeader.biSize = sizeof( stBmpInfo.bmiHeader ); stBmpInfo.bmiHeader.biBitCount = 0; GetDIBits( p\_hDC, hBmp, 0, 0, NULL, &stBmpInfo, DIB\_RGB\_COLORS ); ULONG iBmpInfoSize; switch( stBmpInfo.bmiHeader.biBitCount ) { case 24: iBmpInfoSize = sizeof(BITMAPINFOHEADER); break; case 16: case 32: iBmpInfoSize = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)\*3; break; default: iBmpInfoSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) \* ( 1 << stBmpInfo.bmiHeader.biBitCount ); break; } PBITMAPINFO pstBmpInfo; if( iBmpInfoSize != sizeof(BITMAPINFOHEADER) ) { pstBmpInfo = (PBITMAPINFO)GlobalAlloc( GMEM\_FIXED | GMEM\_ZEROINIT, iBmpInfoSize ); PBYTE pbtBmpInfoDest = (PBYTE)pstBmpInfo; PBYTE pbtBmpInfoSrc = (PBYTE)&stBmpInfo; ULONG iSizeTmp = sizeof( BITMAPINFOHEADER ); while( iSizeTmp-- ) { \*( ( pbtBmpInfoDest )++ ) = \*( ( pbtBmpInfoSrc )++ ); } } HANDLE hFile = CreateFile( p\_pchFileName, GENERIC\_WRITE, 0, NULL, CREATE\_ALWAYS, FILE\_ATTRIBUTE\_ARCHIVE, NULL ); BITMAPFILEHEADER stBmpFileHder; stBmpFileHder.bfType = 0x4D42; // 'BM' stBmpFileHder.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + iBmpInfoSize + pstBmpInfo->bmiHeader.biSizeImage; stBmpFileHder.bfReserved1 = 0; stBmpFileHder.bfReserved2 = 0; stBmpFileHder.bfOffBits = sizeof(BITMAPFILEHEADER) + iBmpInfoSize; DWORD dRet; //// WRITING //// WriteFile( hFile, (LPCVOID)&stBmpFileHder , sizeof(BITMAPFILEHEADER), &dRet, NULL ); PBYTE pBits = (PBYTE)GlobalAlloc( GMEM\_FIXED | GMEM\_ZEROINIT, stBmpInfo.bmiHeader.biSiz
-
1. Get dimensions of existing HBITMAP 2. Use CreateDIBSection to create an image of the correct size 3. Create a couple of memory DCs 4. Select the images into their own DCs 5. BitBlt from the DC holding the HBITMAP to the one containing the DIBSection 6. Save the DIBSection to disk (you can use the supplied function) 7. Deselect the images from their DCs 8. DeleteObject both images (HBITMAP & DIBSection)
BOOL SaveBitmapFile(HDC p_hDC, LPCTSTR p_pchFileName)
{
HBITMAP hBmp = (HBITMAP)GetCurrentObject( p_hDC, OBJ_BITMAP );BITMAPINFO stBmpInfo; stBmpInfo.bmiHeader.biSize = sizeof( stBmpInfo.bmiHeader ); stBmpInfo.bmiHeader.biBitCount = 0; GetDIBits( p\_hDC, hBmp, 0, 0, NULL, &stBmpInfo, DIB\_RGB\_COLORS ); ULONG iBmpInfoSize; switch( stBmpInfo.bmiHeader.biBitCount ) { case 24: iBmpInfoSize = sizeof(BITMAPINFOHEADER); break; case 16: case 32: iBmpInfoSize = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)\*3; break; default: iBmpInfoSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) \* ( 1 << stBmpInfo.bmiHeader.biBitCount ); break; } PBITMAPINFO pstBmpInfo; if( iBmpInfoSize != sizeof(BITMAPINFOHEADER) ) { pstBmpInfo = (PBITMAPINFO)GlobalAlloc( GMEM\_FIXED | GMEM\_ZEROINIT, iBmpInfoSize ); PBYTE pbtBmpInfoDest = (PBYTE)pstBmpInfo; PBYTE pbtBmpInfoSrc = (PBYTE)&stBmpInfo; ULONG iSizeTmp = sizeof( BITMAPINFOHEADER ); while( iSizeTmp-- ) { \*( ( pbtBmpInfoDest )++ ) = \*( ( pbtBmpInfoSrc )++ ); } } HANDLE hFile = CreateFile( p\_pchFileName, GENERIC\_WRITE, 0, NULL, CREATE\_ALWAYS, FILE\_ATTRIBUTE\_ARCHIVE, NULL ); BITMAPFILEHEADER stBmpFileHder; stBmpFileHder.bfType = 0x4D42; // 'BM' stBmpFileHder.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + iBmpInfoSize + pstBmpInfo->bmiHeader.biSizeImage; stBmpFileHder.bfReserved1 = 0; stBmpFileHder.bfReserved2 = 0; stBmpFileHder.bfOffBits = sizeof(BITMAPFILEHEADER) + iBmpInfoSize; DWORD dRet; //// WRITING //// WriteFile( hFile, (LPCVOID)&stBmpFileHder , sizeof(BITMAPFILEHEADER), &dRet, NULL ); PBYTE pBits = (PBYTE)GlobalAlloc( GMEM\_FIXED | GMEM\_ZEROINIT, stBmpInfo.bmiHeader.biSiz
-
Thanks for your reply. Do you think writing the DIB to a xml file and reading back and displaying it will actually display it?
Do you think writing the DIB to a xml file and reading back and displaying it will actually display it?
Well that is the tricky part - it is important to choose what kind of DIB you want, so you can read it latter on Mac: - choose how many colors - by default DIB is bottom-up. If Mac can't read it put negative height in DIB - if Mac can read .bmp, consider writing the file in .bmp rather .xml (this will greatly reduce file size and writing routines to read .xml) Good luck. -
Thanks for your reply. Do you think writing the DIB to a xml file and reading back and displaying it will actually display it?
My pleasure. Sure, writing a bitmap to an XML file will work, it'd just be more work than saving the DIBSection to a BMP file (the code supplied will create a BMP file) You'll be able to open the created file with photoshop or any other image program that supports BMP. I wrote the code from scratch, the BMP format is really fairly simple. Just use your preferred method, either would work.
-
My pleasure. Sure, writing a bitmap to an XML file will work, it'd just be more work than saving the DIBSection to a BMP file (the code supplied will create a BMP file) You'll be able to open the created file with photoshop or any other image program that supports BMP. I wrote the code from scratch, the BMP format is really fairly simple. Just use your preferred method, either would work.
-
I have a handle to bitmap. I need to store this bitmap to a xml file. The xml file will be read on a mac system. So how do I create a DIB from a HBITMAP? Thanks..
What image format does the bitmap need to be in for the Mac to read it? It seems to me there's three steps here: 1) Write the DDB to an image stream in some Mac-recognizable format 2) Send the stream bytes via XML 3) Extract the byte stream into an image Which part is giving you trouble? Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
I have a handle to bitmap. I need to store this bitmap to a xml file. The xml file will be read on a mac system. So how do I create a DIB from a HBITMAP? Thanks..
-
What image format does the bitmap need to be in for the Mac to read it? It seems to me there's three steps here: 1) Write the DDB to an image stream in some Mac-recognizable format 2) Send the stream bytes via XML 3) Extract the byte stream into an image Which part is giving you trouble? Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
The first part. 1) Write the DDB to an image stream in some Mac-recognizable format I thought of writing the BITMAP structure field by field to the xml, including the color bits(pBmBits field). I convert this bmbits field to string before writing. Somehow the size of the xml file after writing the image data increases to 6MB, while the image is only 66KB. Is it OK to convert it to string before writing? How can I convert it to a stream?
-
The first part. 1) Write the DDB to an image stream in some Mac-recognizable format I thought of writing the BITMAP structure field by field to the xml, including the color bits(pBmBits field). I convert this bmbits field to string before writing. Somehow the size of the xml file after writing the image data increases to 6MB, while the image is only 66KB. Is it OK to convert it to string before writing? How can I convert it to a stream?
ThisIsMeRon wrote:
Write the DDB to an image stream in some Mac-recognizable format
What would that format be? Do you need to break apart the bitmap and just send basic info like height, width, bits-per-pixel, and the pixel bits? Or can you send a stream of a "universal" image format like TIFF, JPEG, etc. (the Mac probably reads BMPs fine as well I would think). 66K to 6MB .... definitely something wrong there :) Even if you send a base64 representation of the binary data, you should only see an increase of 33%.
Mark Salsbery Microsoft MVP - Visual C++ :java: