处理巨大的位图

时间:2011-12-15 06:58:24

标签: windows winapi visual-c++ gdi

我需要在我的MFC / WinAPI应用程序窗口上显示位图。位图大小可以是各种各样的 - 例如40MB,100MB,500MB,700MB,1GB等。应该使用滚动条显示不适合应用程序窗口的巨大位图。

问题是,即使通过CreateFileMapping + CreateDIBSection分配内存,系统也无法为某些大尺寸创建位图。

是否有处理此类案件的方法?我想我需要在许多小块上划分我的位图,但我不确定这是正确的方法。

2 个答案:

答案 0 :(得分:2)

您无法创建多大的位图大小?您可能遇到的限制是虚拟地址空间,对于32位代码,它是2GB,3GB或4GB - 具体取决于环境。最直接的解决方案是转移到64位代码。

要呈现此图像,您可能希望实现一个自定义窗口/控件,将源图像的一部分打印到客户区域,并管理滚动条以使用户能够浏览图像。与多年来开发的支持scollbar的窗口相比,实现此类窗口的可能性不大。 Scroll Bar Functions告诉你。

更新CreateFileMapping / MapViewOfFile

使用CreateFileMapping分配的内存不会立即映射到进程地址空间,这使您可以选择分配超出映射的内容。请注意,在满足分配请求时,Windows实际上并未保留实际页面,系统仅检查此类分配是否可行,并将在以后有效地按需分配。

您可以使用这个简单的探针工具FileMappingVirtualAddress.exe来查看整个过程的工作原理,并估算出您可以在应用中分配的数量。该实用程序在启动时尽可能多地执行CreateFileMapping 256 MB块,并通过手动选中一个框,对现有文件映射执行MapViewOfFile。您将能够看到真正的限制是虚拟地址空间(2,3或4 GB,具体取决于环境),但这并不意味着您无法分配更多。

enter image description here

另请注意,如果您为大块请求MapViewOfFile,系统需要使用连续的地址块来满足此要求,因此需要提供此地址空间并且空间碎片可能存在问题。

使用大型位图,您可以实际上不需要完整的位图,并且可以按平铺处理图像。

您还可以截取下载链接并浏览Trac for 64位版本和不使用/LARGEADDRESSAWARE构建的32位版本,以了解它们的不同之处。

答案 1 :(得分:0)

Windows中的总GDI资源和单个位图大小是受限资源。同时,普通阵列大小仅受虚拟地址空间和可用物理内存的限制。因此,您需要将整个图像保持为普通像素数组,仅将所需部分转换为GDI位图以供显示。