【发布时间】:2012-02-19 19:43:26
【问题描述】:
我有一个 MFC 控件,我向其传递位图 (HBITMAP) 的句柄。在控件 OnPaint 方法中,我使用 BitBlt 来呈现位图。但是位图被颠倒了。
作为测试,我从这个句柄创建了一个 CBitmap 对象并将其写入一个文件,它创建了一个正面朝上的位图。那么我对 BitBlt 的调用是否有问题?
我在下面的 OnPaint 中发布了我的代码。我确实尝试将我的设备上下文的映射模式更改为 MM_LOENGLISH 并且能够使位图正面朝上呈现,但它非常粗糙。当我离开 MM_TEXT 的映射模式时,图像的质量是完美的,但正如我所说,它是颠倒的。我对位图、blitting 等工作不多……所以我可能会遗漏一些简单的东西。任何其他建议将不胜感激。对于某些背景,我从摄像机驱动程序中获取 BYTE* 并创建 HBITMAP 来渲染视频。 我怎样才能让它正确渲染?非常感谢
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);
}
编辑* 我假设因为我可以将位图以正确的方向保存到磁盘,所以问题出在 bitblt 上。这是我用来生成 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;
}
哦,我使用了临界区,因为我将 hbitmap 传递给属性中的控件,然后在 OnPaint 中访问它。如果这是一个潜在的问题,我将不得不重新考虑。谢谢
【问题讨论】:
-
这可能与您创建
_handleBMP的方式有关,而不是与您绘制它的方式有关。 -
这几乎肯定在创建位图的代码中开始出错。请注意,扫描线是倒置存储的。顺便说一句,EnterCriticalSection 是绘画代码中的一个危险信号,GDI 从根本上不是线程安全的。