拼凑25M~2G图片,超过253M提示参数无效或内存不够

拼接25M~2G图片,超过253M提示参数无效或内存不够
本帖最后由 Merlin_Bloom 于 2013-08-19 12:17:46 编辑
PC配置:Inter I7 + 8G DDR3内存,1T硬盘;
环境:VS C#.NET 2010;
需求:拼接若干张25M左右的小图片,最终的图片可达500M~2G不等;
进展:已实现图像拼接,上下左右拼接几张均正常;
问题:
1,> 在行或者列,数值超过65535的时候,参数报错,无法拼接;
2,> 虽然单独的width 或 height 没有超过65535,但是相乘超过(65535*4054 约为253M)后,也无法创建图像。

代码举例:
private Bitmap Merge2(Bitmap bmp2, Bitmap bmp1, int dirct)
{

int width, stride, height, length;
length1 = bmp1.Height * bmp1.Width * stepW; 
width = bmp1.Width; // eg: 65536
height = bmp1.Height + iUdHeightNew;
bmp = new Bitmap(width, height,System.Drawing.Imaging.PixelFormat.Format32bppPArgb);

....
}

代码中,最后带下划线那一行,报错:参数无效(或内存不够),坑爹了,超过参数范围,怎么办!
(我现在是计算bmp2,bmp1合并后的大小,照此先创建一个新bmp,然后逐个读进去。)


------解决思路----------------------
分块往文件流里写。。打完收工
------解决思路----------------------
还不是相同的问题,系统无法为你分配那么大的连续内存。
------解决思路----------------------
巧啊,本人前段时间也是遇到这个问题。以为是c#内部的限制。后来经过测试,不同的内存配置,这个最大尺寸也是改变的。最简单暴力的方式就是增加内存。当然,你也可以使用第三方开源库,比如GDAL。好使,好使,太好使了!
------解决思路----------------------
LZ的机器是8G的内存,也会受到限制?LZ是32位还是64位系统?
------解决思路----------------------
我记得BMP文件是由一个固定长度的文件头和内容(数据)区组成的吧?
那么其实直接操作文件流应该更好一些。
比如a.bmp和b.bmp合并成c.bmp,其实只需要直接创建c.bmp,写文件头的时候把长宽计算对,然后数据区就分别读a,b文件进来就好了,好像最多要注意一个什么每行字节补齐还是什么的操作?搜一下BMP文件格式就ok了。

------解决思路----------------------
GDI+中的bitmap大小是按照机器位数计算的,好像32位不能分配到20000*20000,64位没这个限制,但是位图大小占用内存可能会超过你的实际内存,所以还是会报错。这样就先创建位图的缓存硬盘文件,然后一段段写进去就行了。

也就是1楼说的,打完收工。
------解决思路----------------------
你文件大小几百M,在内存显示或处理却是要十几G或以上的,这个时候拼接不能用内存方式,用写文件方式实现,GDAL有栅格处理的,拿来用就好。题外话,拼那么大的图像,打开也是吃力的
------解决思路----------------------
其实,图像在计算机硬盘上存储的时候,是一个文件还是几个文件共同保存一个图像本身没有什么区别,显示的时候,如果你没有超大的显示器的话,对于一个超大的图像也是要分块显示的,如果要整体显示,受到你的显示器的限制,这个整体图像的分辨率是不需要很大的。如果你的显示器足够大,你的显卡内存就会很大。你需要经过加大显卡内存进行显示。也有通过显卡内存进行图像计算的。
------解决思路----------------------
这么大的图片文件恐怕直接使用Bitmap类是无法做到了, 必须直接和内存 以及图片格式打交道吧
数据内存方面我觉得 要么自己维护一个大数据结构(不过图片能到2g,这个方法估计也不会太靠谱)
要么就是 “Windows内存映射文件”的方法了
至于图片编码格式嘛 我也就只能想到bmp这样的不压缩直接按像素读写的方法了……