我想创建一个大的CompatibleDC,在其上绘制一个大图像,然后将部分图像bitblt到其他DC,以实现高性能。
我使用以下代码创建兼容的Memory DC。但是当rect变得非常大,等等: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);
}
答案 0 :(得分:2)
不是创建一个大的DC,然后将另一个较小的DC的一部分blit,而是创建一个与目标DC相同大小的DC,或者至少与blit目标相同的大小。然后,通过要复制的子节的(-x,-y)偏移所有绘图命令。如果您的目的地是(100,200) - (400,400)在源上,然后创建一个DC(300x200)并将所有内容偏移(-100,-200)。
这有两个很大的优点:首先,所需的内存要小得多。其次,GDI会将您的绘图操作剪辑为DC的大小(无论如何它总是剪辑)。虽然裁剪行为需要占用CPU时间,但是不绘制不超过的像素所节省的时间就足以弥补它。
现在,如果这个大型DC类似于图像(例如JPEG),那么您需要查看其他方法。许多图像编辑程序使用的一种技术是将图像分割成图块并将图块分页到存储器/硬盘或从存储器/硬盘分页。每个磁贴都是自己的DC,并且只有足够的源DC来填充目标DC。当视图窗口在大图像上移动时,卸载已移出目标矩形的图块并加载已变为可见的图块。
答案 1 :(得分:0)
每个5000x5000像素图像需要大约100MB的RAM。根据您的PC有多少RAM,这可能已成为问题所在。
如果你有1GB或更多RAM,那可能不是问题。在这种情况下,您必须有内存泄漏。你在哪里释放分配的位图?我看到你没有实现画笔,但位图怎么样?
请注意,增加交换无效,因为这会影响您的效果。
答案 2 :(得分:0)
确保选择DC的所有原始GDI对象。
问题可能是您的Bitmap在被销毁时仍然被选中到pOutputMemDC中,并且其中一个或两个都无法正确删除。因此,记忆问题可能会开始。