如何在C++/MFC / GDI中创建非常大的位图
How to create a very big bitmap in C++/MFC / GDI
我希望能够在 C++ MFC 应用程序中创建一个大(比如 20,000 x 20,000)像素位图,使用 CDC 派生类写入位图。 我已尝试使用 MSDN 文档中所述的内存 DC,但这些内存 DC 似乎仅限于与当前显示驱动程序兼容的大小。
我目前正在使用位图打印驱动程序来完成这项工作,但由于假脱机 GDI 信息,它非常慢并且使用非常大量的中间存储。
我正在寻找的解决方案不应涉及图元文件或假脱机,因为我正在绘制的模型需要数百万次 GDI 调用才能呈现。
我可以通过多个内存 DC 使用分而治之的方法,但这似乎是一种非常繁琐和不优雅的技术。
有什么想法吗?
CDC和CBitmap似乎只支持与设备相关的位图,你可能会更幸运地使用::CreateDIBSection创建位图,然后将CBitmap附加到该位图。不幸的是,原始 GDI 接口有点陈旧。
至少在 32 位应用程序中,20,000 x 20,000 在 32 BPP 下可能不会有太多运气,因为它的内存约为 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));
这是不寻常的,因为我经常基于屏幕创建一个 DC,该 DC 将用于比屏幕大得多的位图图像 - 在某些情况下为 3000 像素以上 - 完全没有问题。 您是否有一些示例代码显示此问题?
考虑到如此大的图像分辨率,您无法使用兼容的位图创建图像。
例:
像素深度 = 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+ 创建部分图像,然后将它们一起呈现。当然,这需要一些实验/优化才能达到完美的用户感觉。
祝你好运
为了将内存使用量保持在可接受的范围内,您必须使用"分而治之"策略。这不是黑客,如果实现正确,它实际上是处理无限大小位图的一种非常优雅的方式。如果你设计得当,你可以将"仅渲染/显示图像的一部分"、"以低分辨率渲染整个图像以在屏幕上显示"和"将整个东西渲染到磁盘位图"方法组合在一个引擎中,并保护代码的用户(很可能在两周内;))免受内部因素的影响。我开发的产品具有相同的问题:渲染(可能很大)映射到屏幕或.bmp文件。
如果图像必须是此分辨率(例如 X 射线的高分辨率扫描),那么您可能需要考虑为其编写自定义假脱机例程 - 1.5 GB 非常昂贵 - 即使对于现代台式机也是如此。
如果它是基于矢量的,那么您可以查看 SVG,因为它支持视口,并且大多数允许您渲染为其他格式。我通过蜡染(java)使用SVG到JPG,所以这是可能的。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 使用std::multimap迭代器创建std::list
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 使用CMake创建QML插件
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 试图在visual studio上用C++创建一个桌面应用程序
- 我刚刚创建了一个非常快速的素数排序方法.如何改进?
- 在64位系统上创建一个非常大的数组的缺点是什么
- 在获得用户的2个输入后,需要以非常具体的方式创建乘法表
- DirectX 11 - 如何创建非常简单的 2D 纹理
- 在使用Qt Creator创建一个非常简单的项目时,在Qt中遇到"segmentation fault"
- 我怎样才能创建一个非常愚蠢的QWidget
- 如何创建非常大的唯一整数数组
- 在GUI中创建非常大的树状视图(超过1M个项目)
- 我想用C++创建一个非常简单的跨平台浏览器.从哪里开始
- 使用非常大的文件创建dll
- 如何在C++/MFC / GDI中创建非常大的位图