3

我想创建一个大的CompatibleDC,在上面画一个大的图像,然后bitblt部分图像到其他DC,以达到高性能。

我正在使用以下代码来创建兼容的 Memory DC。但是当矩形变得非常大时,等等:5000*5000,创建的 CompatibleDC 变得不稳定。有时还可以,有时却失败了。我的代码有什么问题吗?

input :pInputDC
output:pOutputMemDC

{
    pOutputMemDC=new CDC();
    VERIFY(pOutputMemDC->CreateCompatibleDC(pInputDC));

    CRect rect(0,0,nDCWidth,nDCHeight);
    CBitmap bitmap; 
    if (bitmap.CreateCompatibleBitmap(pInputDC, rect.Width(), rect.Height()))
    {
        pOutputMemDC->SetViewportOrg(-rect.left, -rect.top);
        m_pOldBitmap = pOutputMemDC->SelectObject(&bitmap);
    }
    CBrush brush;
    VERIFY(brush.CreateSolidBrush(RGB(255,0, 0)));
    brush.UnrealizeObject();
    pOutputMemDC->FillRect(rect, &brush);
}
4

3 回答 3

2

与其创建一个大的 DC,然后将它的一部分连接到另一个较小的 DC,不如创建一个与目标 DC 大小相同或至少与 blit 目标大小相同的 DC。然后,通过要复制的子部分的 (-x,-y) 偏移所有绘图命令。如果您的目标是源上的 (100,200)-(400,400),则创建一个 DC (300x200) 并将所有内容偏移 (-100,-200)。

这有两大优势:首先,所需的内存要小得多。其次,GDI 会将您的绘图操作剪辑到 DC 的大小(无论如何它总是剪辑)。尽管裁剪操作需要 CPU 时间,但不绘制看不见的像素所节省的时间弥补了这一点。

现在,如果这个大型 DC 类似于图像(例如 JPEG),那么您需要研究其他方法。许多图像编辑程序使用的一种技术是将图像分割成块并将块分页到内存/硬盘或从内存/硬盘分页。每个图块都有自己的 DC,而您只有足够的源 DC 来填充目标 DC。当视图窗口在大图像上移动时,卸载已移出目标矩形的图块并加载已变为可见的图块。

于 2009-05-19T08:36:21.500 回答
0

每个 5000x5000 像素的图像需要 ca。100MB 内存。根据您的 PC 有多少 RAM,这可能已经是问题所在。

如果您有 1GB 或更多的 RAM,那么这可能不是问题。在这种情况下,您必须有内存泄漏。你在哪里释放分配的位图?我看到您没有意识到画笔,但是位图呢?

请注意,增加您的交换将无济于事,因为这会影响您的表现。

于 2009-05-19T08:04:09.910 回答
0

确保将所有原始 GDI 对象选择到 DC。

问题可能是您的位图在被销毁时仍被选择到 pOutputMemDC 中,并且其中之一或两者都无法正确删除。因此,内存问题可能会开始。

于 2009-05-19T09:59:43.390 回答