使用ImageResizer调整大图片大小及内存异常问题

4

在使用ImageResizer.Net调整9000x9000像素的图片大小时,我遇到了内存不足的异常错误(在32位系统上):

ImageBuilder.Current.Build(imageFileName, outputFileName, settings, true);

我可以通过流来成功调整大型图像的大小:

using (var stream = new FileStream(imageFileName, FileMode.Open, FileAccess.Read))
using (var img = Image.FromStream(stream, true, false))
{
    ImageBuilder.Current.Build(img, outputFileName, settings);
    stream.Close();
}

但是,即使经过x次循环,这种最后的方法仍然会遇到内存不足异常。ImageResizer存在巨大的内存泄漏吗?还是我的代码有错误?无论哪种情况,都有解决方法吗?
3个回答

5
如果你要处理810万像素的图像,那么你需要使用64位系统。即使只是解压缩图像,也需要350到800MB连续内存。在32位系统上(即使安装了16GB内存),.NET进程最初只能使用约1200MB的内存。由于内存碎片化(而不是内存泄漏!),该1200MB将被分成50-100MB的小块。因为你需要以800MB为单位的内存(因为你正在处理大型图像),所以这很快就会停止工作。要让.NET对抗内存碎片化,你需要给它足够的时间和额外的空间。在64位系统上,进程应该能够访问足够的RAM,以便在这些工作负载下.NET运行时不会饿死。

很遗憾,在这个开发阶段,升级到64位机器是不可能的。在该机器上运行Photoshop并进行高级图像编辑是可能的,因此也许我应该寻找一个带有.NET包装器的非托管库? - MariaSnuggles
1
Photoshop有自己的虚拟RAM系统和专用页面文件。将页面换出到磁盘是杀死服务器最快的方法 - 这就是我们禁止这样做的原因。你在这里与基本限制作斗争。即使是libvips,可能是唯一从头开始为低RAM条件下的千兆像素图像设计的库,也会在这些条件下表现不佳。 - Lilith River
啊,我实际上是在使用ImageResizer作为桌面应用程序中的图像缝合、裁剪和调整大小的手段,所以分页并不是那么重要,只要成功就行! - MariaSnuggles

0

正如计算机语言学家在他们自己的答案的评论中提到的,libvips能够在使用(更少的)内存的情况下调整大小大尺寸的图像。【实际上,我最终使用了命令行版本,因为我没有找到任何库本身的.NET封装程序。】

在我的情况下,我试图调整大小的图像是21,920×14,610像素。 ImageResizer成功地调整了一个PNG版本(15+ MB)的图像,但对于一个JPEG版本(22+ MB),它抛出了一个 OutOfMemoryException 异常。

我在一台配备8 GB RAM的计算机上运行Windows 7 64位操作系统。


0

我认为你可能在进行一些大型图像调整时耗尽了RAM(但不确定)。

尝试使用DiskCache插件: http://imageresizing.net/plugins/diskcache http://imageresizing.net/download

它将直接将调整大小后的图像写入磁盘,绕过任何RAM问题。而且速度非常快。

很抱歉只能回答“尝试这个”评论,因为我的SO声望不足,无法编写评论。


首先,我正在直接读写文件系统,这与磁盘缓存插件的本质相同? - MariaSnuggles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接