调整大小和裁剪,内存不足
本文关键字:内存不足 裁剪 调整 | 更新日期: 2023-09-27 18:21:17
我有一个小方法,可以调整图像的大小并裁剪它,但在它工作了几个小时后,它突然开始给我OutOfMemory异常。我做错了什么?我认为异常发生在return bmp.Clone(cropArea, bmp.PixelFormat);
上
private static Bitmap Resize(Bitmap image, int width, int height)
{
double scaleH = (double)height / image.Height;
double scaleW = (double)width / image.Width;
double scale = 1.0;
if (image.Width * scaleH >= width)
scale = scaleH;
else if (image.Height * scaleW >= height)
scale = scaleW;
var scaleWidth = (int)(image.Width * scale);
var scaleHeight = (int)(image.Height * scale);
using (var bmp = new Bitmap((int)scaleWidth, (int)scaleHeight))
{
using (var graph = Graphics.FromImage(bmp))
{
graph.DrawImage(image, new Rectangle(0, 0, scaleWidth, scaleHeight));
}
int xStart = (bmp.Width - width) / 2;
int yStart = (bmp.Height - height) / 2;
Rectangle cropArea = new Rectangle(xStart, yStart, width, height);
return bmp.Clone(cropArea, bmp.PixelFormat);
}
}
解决方案这是一个舍入问题,裁剪矩形比图像大,它本身就是
var scaleWidth = (int)Math.Ceiling(image.Width * scale);
var scaleHeight = (int)Math.Ceiling(image.Height * scale);
最初我以为是因为你在最初的问题中出现了内存泄漏
Bitmap target = new Bitmap(width, height);
...
target = bmp.Clone(cropArea, bmp.PixelFormat);
您需要将克隆分配给一个临时变量,处理目标所指向的实例,然后返回目标。
如果你真的使用了目标,你会想做这个
temp = bmp.Clone(cropArea, bmp.PixelFormat);
target.Dipose();
target = temp;
但你注意到这不再是问题所在(你更新的示例没有这个问题),根据我所知,你问题中的代码似乎不是问题所在,你可能有内存泄漏,MSDN在这里有更多关于它的信息。如果您提供使用包装非托管资源的对象的代码,我可能能够判断这是否是内存泄漏。
另一种可能性
也有可能是位图太大,以至于您的程序可用内存不足,如果您能让我们了解有关位图的更多信息,程序在上失败会更容易判断