I have an MFC control to which I pass a handle to a bitmap (HBITMAP). In the controls OnPaint method I am using BitBlt to render the bitmap. But the bitmap is being rendered upside down.
As a test I created a CBitmap object from this handle and write that out to a file and it created a bitmap that was right side up. So am I doing something wrong with my call to BitBlt?
I've posted my code from OnPaint below. I did try to change the mapping mode of my device context to MM_LOENGLISH and was able to get the bitmap to render right side up but it was very grainy. When I leave the mapping mode at MM_TEXT the quality of the image is perfect but as I said it is upside down. I haven't worked much with bitmaps, blitting etc...so I could be missing something easy. Any other suggestions would be appreciated. For some background I'm grabbing a BYTE* from a video camera driver and creating the HBITMAP to render the video. How can I get this to render properly?? Many thanks
void BitmapControl::OnPaint() { EnterCriticalSection (&CriticalSection); if (_handleBMP) { CPaintDC dc(this); //dc.SetMapMode(MM_LOENGLISH); CDC dcMem; dcMem.CreateCompatibleDC(&dc); CRect rect; GetClientRect(&rect); dc.DPtoLP(&rect); CBitmap* pBmpOld = dcMem.SelectObject(CBitmap::FromHandle(_handleBMP)); BitBlt(dc,rect.left,rect.top,rect.Width(),rect.Height(),dcMem,rect.left,rect.top,SRCCOPY); //works with MM_TEXT but upsidedown //BitBlt(dc,0,rect.bottom,rect.Width(),-rect.Height(),dcMem,0,0,SRCCOPY); //works with MM_LOENGLISH dcMem.SelectObject(pBmpOld); DeleteDC(dc); DeleteDC(dcMem); DeleteObject(_handleBMP); DeleteObject(pBmpOld); _handleBMP = NULL; } LeaveCriticalSection (&CriticalSection); }
edit* I was assuming because I could save the bitmap to disk in the correct orientation that the problem was with bitblt. Here is the code I use to generate the HBITMAP.
HBITMAP BitmapWriter::CreateBitmapFromFrame(BYTE* frame) { BITMAPFILEHEADER* bmfh; bmfh = (BITMAPFILEHEADER*)frame; BITMAPINFOHEADER* bmih = &_bmi; BITMAPINFO* bmpInfo = (BITMAPINFO*)bmih; HBITMAP hbmp = CreateDIBSection(_hdc,bmpInfo,DIB_RGB_COLORS,NULL,NULL,0); SetBitmapBits(hbmp,_bmi.biSizeImage,frame); return hbmp; }
Oh, and I used the critical section because I pass the hbitmap to the control in a property and then access it in the OnPaint. If that's a potential problem I will have to rethink that. Thanks