如何在C ++ / MFC / GDI中创建很大的位图

时间:2020-03-06 14:46:11  来源:igfitidea点击:

我希望能够使用CDC派生类向C ++ MFC应用程序中创建一个大(例如20,000 x 20,000)像素的位图。我已经尝试按照MSDN文档中的描述使用内存DC,但是这些DC似乎仅限于与当前显示驱动程序兼容的大小。

我目前正在使用位图打印驱动程序来完成这项工作,但是由于假脱机处理GDI信息,它的运行速度非常慢并且使用了大量的中间存储。

我正在寻找的解决方案不应涉及图元文件或者假脱机,因为我正在绘制的模型需要数百万个GDI调用来呈现。

我可以通过多个内存DC使用分而治之的方法,但这似乎是一种非常繁琐和不雅观的技术。

有什么想法吗?

解决方案

这是不寻常的,因为我经常基于屏幕创建DC,该DC将用于位图图像,该位图图像比屏幕大3000像素,并且在某些情况下完全没有问题。我们是否有一些示例代码显示了该问题的实际执行情况?

CDC和CBitmap似乎仅支持与设备有关的位图,如果使用:: CreateDIBSection创建位图,然后将CBitmap添加到该位图上,我们可能会更幸运。不幸的是,原始的GDI接口有点老套。

至少在32位应用程序中,至少在32位应用程序中,20,000 x 20,000可能不会带来20,000 x 20,000的运气,因为这大约需要1.5 GB的内存,但是我得到的有效HBITMAP为16 bpp:

BITMAPINFOHEADER bmi = { sizeof(bmi) };
bmi.biWidth = 20000;
bmi.biHeight = 20000;
bmi.biPlanes = 1;
bmi.biBitCount = 16;
HDC hdc = CreateCompatibleDC(NULL);
BYTE* pbData = 0;
HBITMAP hbm = CreateDIBSection(hdc, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (void**)&pbData, NULL, 0);
DeleteObject(SelectObject(hdc, hbm));

考虑到如此大的图像分辨率,我们不能使用兼容的位图创建图像。

例子:

像素深度= 32位=每个像素4个字节

像素数= 20.000 * 20.000 = 400.000.000

总字节数=像素数* 4 = 1.600.000.000字节= 1.562.500 kb〜= 1525 MB〜= 1.5GB

我正在猜测最终的意图,但是假设我们要创建并允许用户使用非常详细的缩放比例浏览巨大的地图。
我们应该创建自定义图像文件格式;我们可以在该文件中放入包含位图网格的各种图层,例如,以加快渲染速度。渲染过程可以使用GDI DIB或者GDI +创建部分图像,然后将它们一起渲染。当然,这需要一些试验/优化才能达到完美的用户感觉。

祝你好运

如果图像必须是这种分辨率,请说说要对X射线进行高分辨率扫描,那么我们可能想看看为其编写自定义假脱机例程,即使对于现代台式机,1.5 gb也非常昂贵。

如果它是基于矢量的,则可以查看SVG,因为它支持视口,并且大多数允许我们渲染为其他格式。我通过Batik(java)使用SVG到JPG,所以可以做到。

为了使内存使用率保持在可接受的范围内,我们必须使用"分而治之"的策略。这不是黑客,如果正确实施,实际上是处理无限大小位图的一种非常优雅的方法。如果设计正确,则可以结合使用"仅渲染/显示图像的一部分","以低分辨率渲染整个图像以在屏幕上显示"和"将整个对象渲染到磁盘位图"的方法。一个引擎,使代码用户(很可能在两周之内就可以做到;))免受内部攻击。我使用的产品存在以下问题:渲染(可能很大)映射到屏幕或者.bmp文件。