[英]Resize and Crop, Out of memory
我有这个小方法,可以调整图像大小并裁剪图像,但是在工作了几个小时之后,它突然开始给我OutOfMemory Exception。 我究竟做错了什么? 我认为异常是在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);
您需要将克隆分配给一个临时变量,处理实例目标指向的对象,然后返回目标。
如果您确实将target用于某物,则需要这样做
temp = bmp.Clone(cropArea, bmp.PixelFormat);
target.Dipose();
target = temp;
但是您从我可以告诉您的问题中的代码看来不再是问题(您的更新示例中没有此问题),这似乎不是问题,您可能存在内存泄漏,MSDN提供了更多信息关于这里 。 如果您在使用包装非托管资源的对象的地方提供代码,那么我也许可以弄清楚这是否是内存泄漏。
位图可能太大,以至于您的程序可用内存不足,这很容易告诉您是否可以让我们知道有关程序失败的位图的更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.