如何在GDI编程中创建一个大的兼容内存设备上下文?

3

I want to create a large CompatibleDC, draw a large image on it, then bitblt part of the image to other DC, in order to achieve high performance.

I am using the following code to create compatible Memory DC. But when the rect becomes very large, etc: 5000*5000, the CompatibleDC created become unstable. sometimes it is OK, sometimes it failed. is there any thing wrong with my code?

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


GetLastError 返回什么? - user253751
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。随着视窗在大型图像上移动,卸载已移出目标矩形的瓦片并加载已变得可见的瓦片。


0
每个 5000x5000 像素的图像需要大约 100MB 的RAM。 根据您的PC有多少RAM,这可能已经是问题所在。
如果您有1GB或更多的RAM,那么这可能不是问题。 在这种情况下,您必须具有内存泄漏。 您在哪里释放被分配的位图? 我看到您取消实现画笔,但是位图呢?
请注意,增加交换不会有帮助,因为这会降低性能。

0

请确保您选择了所有原始的GDI对象到DCs。

问题可能是当您的位图被销毁时,它仍然被选择到pOutputMemDC中,其中一个或两个无法正确删除。因此,内存问题可能会开始出现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接