我有一个Windows应用程序项目,处理图像编辑(裁剪和调整大小)。不幸的是,这些图像处理消耗了大量的内存和CPU资源(很容易达到600MB或50%cpu),而且只需要裁剪和调整一个重量为2.5MB(2300 * 5400px)的gif图像。更重要的是,由于资源消耗大,程序在调整大小时会卡住......
public static Image Resize(Image imgToResize, Size size)
{
Bitmap b = new Bitmap(size.Width, size.Height);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.Default;
g.SmoothingMode = SmoothingMode.HighSpeed;
g.PixelOffsetMode = PixelOffsetMode.Default;
g.DrawImage(imgToResize, 0, 0, size.Width, size.Height);
g.Dispose();
return (Image)b;
}
public static Image Crop(Image img, Point p1, Point p2)
{
Rectangle cropArea = new Rectangle(p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.Y);
return (img as Bitmap).Clone(cropArea, img.PixelFormat);
}
我应该使用哪些方法来避免这种情况? 我已经尝试将它压缩成几种格式的内存流,但它没有帮助(甚至使它变得更糟)
注意:我使用标准的.NET绘图库:System.Drawing,System.Drawing.Imaging
答案 0 :(得分:3)
您的代码正在创建映像的副本,因此在调用这些方法时,您应该期望非托管内存使用率上升。重要的是你用原版做的事情。你应该明智地摆脱它,这样它就不再占用记忆。您必须调用其Dispose()方法来执行此操作。等待垃圾收集器执行它需要太长时间。 Bitmap类只需很少的托管内存,但需要大量非托管内存。
答案 1 :(得分:1)
从此问题的早期版本开始:http://snippets.dzone.com/posts/show/4336
此外,AForge.net有几个调整大小函数
答案 2 :(得分:0)
这是一个棘手的问题,而且我之前遇到过一个问题。您可以根据文件的大小将图像拆分为x个,然后将每个图像保存到磁盘以确保内存清洁。
接下来,每次调整一个组件映像的大小,确保在继续下一个组件之前处理组件。完成所有操作后,将它们拼接在一起,然后裁剪。
使用这种方法的主要问题 - 如果你正在调整向上,这种方法会在你的图像中加入接缝,因为插值不会有周围的像素猜测。但我认为这种方法适用于向下调整大小。
HTH。
答案 3 :(得分:0)
又一次暗示:
例如在调整大小时,就像@Hans指出的那样,你创建了一个新的Bitmap,哪一个是你的瓶颈。
但是,如果您只是绘制图像已调整大小,最初加载的图像(显然您之前在磁盘上创建了原始图像的备份文件)。
裁剪后,如果您只是绘制用户裁剪的位图的一部分,那么用户将只看到该矩形。 ?
我的意思是一般来说,对你已有的图像进行操作,并尝试(尽可能多)不为它初始化新对象。
问候。
答案 4 :(得分:-2)
编写Application.DoEvents();在你的功能中,至少它不会卡住