最近由于要处理大量图像并将图像拼接为一个大图形,每个图像像素都很大(1280x960),拼接后更大,并且需要对图像频繁进行标记等操作,遇到了很多问题,内存不足,一般性错误,对象错误等等等等。
通过自己的摸索与在网上查找相应网友的经验,自己总结了一套相对较好的代码,满足了自己的需要,并且目前较为稳定的运行。代码并不是最优化,肯定还有更好的解决方法。欢迎大家给出意见和建议。
下面代码中标记出了常见的问题知识点,我先上代码,随后一一解释
Try '----------------知识点一:打开源文件,建立新图像,复制源文件到新图像,释放源文件 '案例 http://www.cnblogs.com/yeahgis/archive/2011/11/12/2246332.html '案例 http://blog.csdn.net/gisoracle/article/details/4961511 <pre class="vb" name="code"> '打开源文件 Dim imageFile As Image = Image.FromFile(strFileLocation + "\JPG\FULL.jpg") Dim destGraphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(imageFile) '操作image destGraphic.DrawImage(otherimage,0) '释放 destGraphic.Dispose() imageFile.Dispose() '将图像加载到PictureBox imgMaster.Image = CType(imageFile.Clone,Image) '保存文件为另外名称 imageFile.Save(AOI_BlockVSRefVIEWER.strFileLocation + "\FOVCOMBINEImages\FULLnew.jpg",AOI_FOV.GetImageFormat("jpg")) System.Windows.Forms.Application.DoEvents() '--------------------知识点二: 注意释放内存资源----------------- '释放源文件防止再操作时忙碌 imageFileTemp.Dispose() '释放Graphic缓解系统内存紧张 destGraphic.Dispose() '-----------------知识点三: 不要释放pictureBox所引用的图像,否则你在该应用程序与其他系统应用程序切换多次后会引起错误。 'imageFile.Dispose() '-----------------知识点四:很多情况即使dispose了仍然内存不足,启用强制垃圾回收大大缓解了 'http://blog.sina.cn/dpool/blog/s/blog_700bf71601018wq6.html?vt=4 GC.Collect() Catch ex As Exception '-----------------知识点五: GDI+一些错误很奇特,只有简单的一般错误提示,而用Marshal这个才能得到有价值的错误信息 '参见http://wenku.baidu.com/view/3cf9556d4afe04a1b171de32.html Marshal.GetLastWin32Error() End Try
知识点一:
很多情况下大家都使用简单的步骤加载图片: 打开源文件赋值给image-> 建立Graphic并对image进行操作->释放Graphic和Image。
一般方法: '打开图像文件 Dim imageFile As Image = Image.FromFile(strFileLocation + "\FOVCOMBINEImages\FULL.jpg") Dim destGraphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(imageFile) '操作图像文件 destGraphic.DrawImage(otherimage,0) '释放 destGraphic.Dispose() imageFile.Dispose()
这种方式大部分情况下不会出现问题,但当图像文件比较大,频繁操作同一个图像时,会发生一般性错误,或者指示文件被其他程序占用。所以采用代码改良后的方法给系统一定缓冲,极大减少了一般性错误和文件被占用的错误产生
知识点二:
这个比较简单,一般大家都有注意,提示内存不足时请务必查看自己是否Dispose了不需要的资源
知识点三:
这个比较容易忽略。 如果窗体上有一个pictureBox,你加载了图片,在处理完后你将image给释放掉了,一般情况下不会出现问题,即使你dispose了那个image,系统会暂存到pictureBox中。 当如果图片过大,系统会在有些时候释放掉。 比方你在打开该窗口后,去执行操作系统下的其他软件或程序,系统根据内存分配会将PictureBox那个清空,当你操作完其他程序后转来点这个窗口时系统会重载pictureBox的image,但image已经被你Dispose了,会出现对象错误的情况。 解决方法就是让该图片驻留到内存,不要Dispose。
知识点四:
当图片实在很大很多,或者一些特殊的情况下,将所有都Dispose掉了仍然会有内存不足,或者一般性错误,这时尝试启用强制垃圾回收GC.collect()
知识点五:
这是使用GDI+比较无语的一个Exception, 里面什么信息都没有。我们可以调用Marshal这个来获取有意义的错误信息。