-
HBITMAP from hdc
I'm trying to save a programatically created 256 grayscale bitmap into a general .bmp file.
I can show the bitmap on screen with this command:
StretchDIBits(hdc, 10, 10, 8, 9, 0, 0,
8, 9, buffer, &bmp_info, DIB_RGB_COLORS, SRCCOPY);
Now I need to get the bitmap into HBITMAP so that I could save it in a .bmp file. How do I do this? I basically know how to save the bitmap to disk after there is something on HBITMAP (i hope) :)
Tried to use this:
hBitmap = CreateCompatibleBitmap(hdc, 8, 9);
but I guess this doesn't contain the actual data on HDC since the bitmap file ended to be totally black.
*s
-
Using following functions you can get HBITMAP from hdc.
CDC::GetCurrentBitmap
--CBitmap* GetCurrentBitmap( ) const;
CBitmap::operator HBITMAP
--operator HBITMAP( ) const;
-
I'm using pure win32 api, sorry forgot to mention. I don't quite understand the answer (but thank you for it anyways! )
-
uhmm...it's been a long time since I messed around with this.
Here's what I did:
Code:
HDC myDC = CreateCompatibleDC(originalDC);
HBITMAP myBMP = CreateCompatibleBitmap(myHDC);
SelectObject(myDC,myBMP);
BitBlt(myDC ,0,0,kWindowWidth,kWindowHeight,originalDC,0,0,SRCCOPY);
where kWindowWidth and height are the width and height of what you're about to copy. IIRC this leaves you with myBMP
containing what you want. :)
This is just out of the back of my head but these functions
(possibly in conjunction with some others) will do the trick.
So look them up at MSDN and I hope you'll be set :).
If this don't work for ya let me know and I'll find out exactly what I did.
/btq :)
-
Try the follwing function. It will help you save bitmap file from hdc.
BOOL CScreenDlg::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;
WriteFile
( hFile, (LPCVOID)&stBmpFileHder
, sizeof(BITMAPFILEHEADER), &dRet, NULL );
PBYTE pBits
= (PBYTE)GlobalAlloc
( GMEM_FIXED | GMEM_ZEROINIT
, stBmpInfo.bmiHeader.biSizeImage );
HBITMAP hBmpOld;
HBITMAP hTmpBmp
= CreateCompatibleBitmap
( p_hDC
, pstBmpInfo->bmiHeader.biWidth
, pstBmpInfo->bmiHeader.biHeight );
hBmpOld = (HBITMAP)SelectObject( p_hDC, hTmpBmp );
GetDIBits
( p_hDC, hBmp, 0, pstBmpInfo->bmiHeader.biHeight
, (LPSTR)pBits, pstBmpInfo, DIB_RGB_COLORS );
WriteFile
( hFile, (LPCVOID)pstBmpInfo
, iBmpInfoSize, &dRet, NULL );
WriteFile( hFile, (LPCVOID)pBits
, pstBmpInfo->bmiHeader.biSizeImage
, &dRet, NULL );
SelectObject( p_hDC, hBmpOld );
DeleteObject( hTmpBmp );
CloseHandle( hFile );
GlobalFree( pstBmpInfo );
GlobalFree( pBits );
return TRUE;
}
-
Thanks for everyone for the replies. :)
I wonder why cr_naik's SaveBitmapFile function captures the whole screen, even though I give it a hdc of a dialog's static-control as a parameter. I would like to create a bitmap of that part only.
I also wonder if the original problem would be solved better if I tried to create a HBITMAP out of a BYTE-table and BITMAPINFO header that are already created. I just don't know how to do this. I was able to display the bitmap on screen with StretchDIBits and that's why I wondered that since I have the pic in hdc let's get it from there to HBITMAP.
Would it be more reasonable to try to create the HBITMAP from BYTE-table and BITMAPINFO-structure, since I already have defined those? How to create a HBITMAP out of BYTE-table? Or what would be the correct way to save a BYTE-table as a .bmp file on disk?
Anybody follow anymore? :)