1

我正在尝试将位图(存储为字节数组)绘制到窗口。

典型程序如下:

在 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);
}
4

1 回答 1

0

如果要将位图绘制到与源图像大小不同的窗口,请尝试使用StretchBlt ,而不是使用 BitBlt :

来自 MSDN:

将位图从源矩形复制到目标矩形,必要时拉伸或压缩位图以适应目标矩形的尺寸。

如果您想要与显示的结果相同的结果,那么您可能正在以最好的方式做到这一点。您可以使用 FillRect 之类的东西直接绘制到 Frame(或处理 OnEraseBkgnd),然后使用 BitBlt 原始大小的图像,但您可能会得到一些闪烁,您的双缓冲解决方案可以解决这个问题。

于 2014-06-16T09:20:29.467 回答