超大图片的储存/处理/显示🌁

大图是指那种G级别,目前测试使用的图片大概是几万乘几万像素的灰度图。也就是其大小内存还是可以读入,但是需要对数据结构进行设计来达到优化使用的目的。
对于那些图片本身信息已经大于内存的数据,只有一些简单的思路,没有实现。
文章里只包含一些问题的总结和思路,没有具体代码和方案。

内存中储存

c++程序里对内存没有限制,只要别大于机器的内存就行。但是C#中有一些奇怪的设定,首先是32位平台下单个程序默认不允许超过2G。这个解决起来比较简单,直接在vs工程中修改某些设置就行(具体的话直接百度吧)。
另外还有一个限制,是我自己总结的,因为没有看到专门说这个的内容,就是单个内存地址,也就是申请的内存,也不能超过2G(具体大小没有测试,大约这个范围)。之所以得出这个结论,是因为在测试申请一个大于2G数组的时候,他会overflow,但是如果你申请的是4个512M的数组,就会一切正常。Mat/Image这两个类也是一样。应该就是他无法取出这么大的连续空间的内存吧。

所以针对这个限制,我的解决方案是设计一个类,来实现大图片的分块读取和存储。为了提高效率,可以直接用byte的二维数据来做块,需要设置每块数据的最大上限,保证不超过(单个连续空间的最大值),同时这个最大上限会对图像的访问效率产生影响,所以需要一定的测试和修改。
这样就可以保证通过多个小内存,来储存一个大数据量图片的目的。

图像浏览

图像浏览这个需求可能就稍微小一点了吧。最典型的大图浏览其实就是地图,谷歌地图,百度地图应该都是用的类似算法–图像金字塔。

其实这个词一说出来这个算法应该就差不多知道了吧。就是在内存里生成一系列不同分辨率大小的图片,根据浏览需求的视场大小,选择合适的分辨率图片,从而输出一个(用户看的比较清楚,同时又尽可能小的图片)。是一种牺牲空间(内存)来换取时间的方式。

超超大图片

这个只是我又自己做的拓展出来的一些思考。

如果图片真的超级大,连内存里也存不下了,就只能用硬盘了。当然这里的硬盘最好是固态的了。其实内存和硬盘本质差不多,不过就是内存的读取速度快一点而已,所以如果图片大小真的超过内存了,那使用硬盘也是没有办法了。

可以在基于分块储存和金字塔的基础上,把一些访问率比较低,或者完整的大分辨率图像,通过某种储存和索引方式,存到硬盘里。(感觉说了和没说一样,难点应该就在于如何设计这种索引方式来达到高效读写吧)

发表回复