C++ MFC:将位图绘制到 CFrame 中
Posted
技术标签:
【中文标题】C++ MFC:将位图绘制到 CFrame 中【英文标题】:C++ MFC: Draw a bitmap into a CFrame 【发布时间】:2014-06-13 17:07:10 【问题描述】:我正在尝试将位图(存储为字节数组)绘制到窗口。
典型程序如下:
在 OnPaint() 处理程序中获取设备上下文。
CPaintDC dc(this);
从中创建兼容的设备上下文,
CDC pMemDC->CreateCompatibleDC(&dc);
创建一个与客户区大小相同的兼容位图 (GetClientRect(&WinRect)
)。
CBitmap pNewBitmap->CreateCompatibleBitmap(&dc, WinRect.Width(), WinRect.Height());
现在,如果窗口客户端的大小与位图的大小完全相同,我可以简单地调用 pNewBitmap->SetBitmapBits
以将我的数组“输入”到位图中。
在后面加上BitBlt
,位图就会出现在窗口上。
dc->BitBlt(0, 0, WinRect.Width(), WinRect.Height(), pMemDC, 0, 0, SRCCOPY);
如果您希望窗口大小独立于图像大小而变化,那么首先您必须确保pNewBitmap
是正确的大小(客户矩形),但现在您不能简单地将数组推入位图中。
在这种情况下,我找到了一个解决方案,方法是重复上述过程来创建一个与图像精确大小的位图,这样我就可以将我的位“推入”其中,然后将BitBlt
放入更大的客户端-大小的位图,然后将BitBlt
'ed 到窗口中。
还有其他方法可以做到这一点吗?实际代码如下。
void CAnimateWnd::OnPaint()
CPaintDC dc(this); // device context for painting
DrawScene(&dc);
// Do not call CWnd::OnPaint() for painting messages
void CAnimateWnd::DrawScene(CDC *pDrawDC)
CRect WinRect;
GetClientRect(&WinRect);
if (pNewBitmap == NULL)
pMemDC = new CDC();
pMemDC->CreateCompatibleDC(pDrawDC);
pNewBitmap = new CBitmap();
pNewBitmap->CreateCompatibleBitmap(pDrawDC, WinRect.Width(), WinRect.Height());
pMemDC->SelectObject(pNewBitmap);
CRect BMPRect;
GetBitmapDrawSize(&BMPRect);
if (BMPRect != NULL)
if (!(BMPRect.Width() >= WinRect.Width() && BMPRect.Height() >= WinRect.Height()))
//The bitmap is smaller than the window, so fill the window with the background color.
CBrush BackBrush(BackGndColor);
CPen BackPen(PS_SOLID, 1, BackGndColor);
pMemDC->SelectObject(&BackBrush);
pMemDC->SelectObject(&BackPen);
pMemDC->Rectangle(&WinRect);
BackBrush.DeleteObject();
BackPen.DeleteObject();
OverrideAndDrawInHere(pMemDC, resize);
pDrawDC->BitBlt(0,0,WinRect.right,WinRect.bottom,pMemDC,0,0,SRCCOPY);
template <class T>
void ImageWindow<T>::OverrideAndDrawInHere(CDC *pDC, int resize)
if (this->sourceImage == NULL) return;
CRect clientRect;
GetClientRect(&clientRect);
if (this->dispBMP == NULL)
this->dispDC = new CDC();
this->dispDC->CreateCompatibleDC(pDC);
this->dispBMP = new CBitmap();
this->dispBMP->CreateCompatibleBitmap(pDC, this->sourceImage->GetWidth(), this->sourceImage->GetHeight());
this->dispDC->SelectObject(this->dispBMP);
this->dispBMP->SetBitmapBits(this->sourceImage->GetArea() * 4, this->translatedImage);
pDC->BitBlt(0, 0, this->sourceImage->GetWidth(), this->sourceImage->GetHeight(), this->dispDC, 0, 0, SRCCOPY);
【问题讨论】:
【参考方案1】:如果您想将位图绘制到与源图像大小不同的窗口,请尝试StretchBlt,而不是使用 BitBlt:
来自 MSDN:
将位图从源矩形复制到目标矩形, 必要时拉伸或压缩位图以适应 目标矩形的尺寸。
如果您希望获得与所展示的结果相同的结果,那么您可能正在以最好的方式做到这一点。您可以使用 FillRect 之类的东西直接绘制到 Frame(或处理 OnEraseBkgnd),然后 BitBlt 原始大小的图像,但您可能会得到一些闪烁,这是您的双缓冲解决方案解决的问题。
【讨论】:
问题是绘制一个比窗口小的位图,没有拉伸它,仍然用纯色填充颜色绘制窗口的其余部分。以上是关于C++ MFC:将位图绘制到 CFrame 中的主要内容,如果未能解决你的问题,请参考以下文章
c++:如何使用 sdl 将位图加载到 opengl 中的多维数据集中?