Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BitBlt drawing bitmap upside down

Tags:

c++

mfc

gdi

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

like image 288
mash Avatar asked Dec 04 '22 18:12

mash


1 Answers

Windows bitmaps are stored with the bottom line first. Most of the rest of the world works top line first, so I presume that's what you're getting from your camera.

You can use a negative height in the BITMAPINFOHEADER structure to reverse the normal order.

like image 61
Mark Ransom Avatar answered Dec 07 '22 07:12

Mark Ransom