我想创建一个大型组合,在其上绘制一个大图像,然后将图像的Bitblt部分绘制到其他DC,以实现高性能。

我正在使用以下代码来创建兼容的内存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);
}
有帮助吗?

解决方案

与其创建大型直流,然后闪烁另一部分,较小的直流,而是创建与目的地DC相同的DC,或者至少与闪电目的地相同的大小。然后,将所有绘图命令取代您要复制的子部分的(-x,-y)。如果您的目的地为(100,200) - (400,400),则创建DC(300x200),然后将所有内容偏移为(-100,-200)。

这有两个很大的优势:首先,所需的内存要小得多。其次,GDI会将您的绘图操作夹在DC的大小上(无论如何它总是剪辑)。尽管剪辑的行为需要CPU的时间,但通过不绘制没有比弥补的时间来节省的时间。

现在,如果此大型DC像图像(例如JPEG),那么您需要研究其他方法。许多图像编辑程序使用的一种技术是将图像分为图块,然后页面将图片划分为/从内存/硬盘。每个瓷砖是其自己的直流,您只有足够的源DC来填充目标直流。当视图窗口跨过大图像时,卸下已经从目标矩形和负载瓷砖移出的瓷砖已经可见了。

其他提示

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

如果您有1GB或更高的RAM,那么这可能不是问题。在这种情况下,您必须有内存泄漏。您在哪里释放分配的位图?我看到您未实现刷子,但是位图呢?

请注意,增加交换无济于事,因为那会杀死您的表现。

确保您选择了DCS的所有原始GDI对象。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top