我正在尝试将位图(存储为字节数组)绘制到窗口。
典型程序如下:
在 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
放入窗口中。
还有其他方法吗?实际代码如下。
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);
}
最佳答案
不要使用 BitBlt,试试 StretchBlt如果您想将位图绘制到与源图像大小不同的窗口:
来自 MSDN:
Copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the bitmap if necessary to fit the dimensions of the destination rectangle.
如果您希望获得与您所展示的相同的结果,那么您可能采用了最佳方式。您可以使用 FillRect 之类的东西直接绘制到框架(或处理 OnEraseBkgnd),然后 BitBlt 原始大小的图像,但您可能会遇到一些闪烁,您的双缓冲解决方案解决了这个问题。
关于C++ MFC : Draw a bitmap into a CFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24210514/