1

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

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

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

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

有什么想法吗?

4

5 回答 5

2

CDC 和 CBitmap 似乎只支持与设备相关的位图,您可能会更幸运地使用::CreateDIBSection创建位图,然后将 CBitmap 附加到该位图。不幸的是,原始的 GDI 接口有点陈旧。

至少在 32 位应用程序中,32 BPP 的 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));
于 2008-09-26T07:27:46.467 回答
1

这是不寻常的,因为我经常基于屏幕创建一个 DC,该 DC 将用于比屏幕大得多的位图图像 - 在某些情况下超过 3000 像素 - 完全没有问题。你有一些示例代码显示这个问题吗?

于 2008-09-26T07:22:01.253 回答
1

考虑到如此大的图像分辨率,您无法使用兼容的位图创建图像。

例子:

像素深度 = 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+ 来创建部分图像,然后将它们一起渲染。当然,这需要一些试验/优化才能达到完美的用户感觉。

祝你好运

于 2008-09-26T07:41:44.357 回答
1

为了将内存使用量保持在可接受的范围内,您必须使用“分而治之”的策略。这不是 hack,如果实施得当,它实际上是一种非常优雅的方式来处理无限大小的位图。如果设计正确,您可以结合“仅渲染/显示图像的一部分”、“以低分辨率渲染整个图像以在屏幕上显示”和“将整个图像渲染到磁盘位图”方法一个引擎并保护您的代码的用户(很可能是您自己在两周内;))免受内部影响。我在使用具有相同问题的产品:将(可能很大)映射到屏幕或 .bmp 文件。

于 2008-09-26T08:19:24.500 回答
0

如果图像必须是这个分辨率——比如 X 射线的高分辨率扫描——那么你可能想看看为它编写自定义假脱机例程——1.5 GB 非常昂贵——即使对于现代台式机也是如此。

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

于 2008-09-26T08:05:40.353 回答