【发布时间】:2012-11-18 21:00:39
【问题描述】:
尝试将巨大的图像(例如 9000x9000 像素的图像)加载到 Bitmap 对象中可能会产生内存不足错误、"Parameter is not valid" error 以及毫无疑问的其他相关问题。
如何从磁盘加载 9000x9000 像素的图像,最终在保存回磁盘之前调整其大小,而不会导致致命错误(例如内存不足)?
让我们假设一个 32 位环境,具有 2gb 的内存,C# 4.0,并且将使用 jpg、gif、bmp、tif、png 的图像格式。
我尝试了以下 3 个 sn-ps,每个都失败并出现内存错误。
尝试 1:
using (Bitmap srcImg = new Bitmap(@"C:\9000x9000.jpg"))
{
// boom
}
尝试 2:
using (Image srcImg = Image.FromFile(@"C:\9000x9000.jpg"))
{
// kapow
}
尝试 3:
using (FileStream fs = new FileStream(@"C:\9000x9000.jpg", FileMode.Open, FileAccess.Read))
{
using (Image srcImg = Image.FromStream(fs))
{
// kelly clarkson
}
}
我对一个可能的解决方案的想法是将图像文件直接加载到一个数组中(这样您就没有 Bitmap 对象的巨大开销),以某种方式使用该数组将其调整为更小(可能需要为不同的图像编码格式标题?),然后最终转换为可管理大小的位图对象。
想法或可能的解决方案?
【问题讨论】:
-
错误信息是什么?首先在一个简单的控制台应用程序中尝试,然后在您的应用程序中应用该解决方案。
-
图片的位深是多少?我很好奇该图像试图消耗多少 RAM。我的猜测是很多,因为 32 位图像意味着至少 310MB。考虑到您的其他问题,我强烈建议您升级到至少 8GB 内存的 64 位系统。可能更多。并且我会建议您使用专为处理如此大的图像而构建的工具
-
您是否真的遇到了错误,或者您只是在猜测可能存在的问题?我认为没有任何先验理由认为 18 Mpx 的图像会引起任何悲伤,除非你真的想把它放大。它将占用几百 MB。
-
@MarceloCantos 他说他实际上尝试过这个问题并提到内存不足和“参数无效”(= ArgumentException)
-
回答:确切的错误是,取决于环境:“参数无效。在 System.Drawing.Bitmap..ctor”(有问题的链接提供了有关错误的信息)和“OutOfMemoryException:Out of内存。在 System.Drawing.Bitmap..ctor"。位图对象是“32 位”(PixelFormat.Format32bppArgb) 以允许 alpha 透明度,例如 png。升级到 64 位系统/8gb 内存是未来可能的选择,但请记住问题指定 32 位/2gb;此外,优化代码以在 32 位/2gb 环境中运行无疑也会使其在 64 位/8gb 环境中更高效。