[英]Out of memory exception when resizing many bitmaps
i need to resize 5000 images and save them in a separate folder.我需要调整 5000 张图像的大小并将它们保存在一个单独的文件夹中。 I have a code like this to create a resized copy of a picture (found on the Internet):
我有一个这样的代码来创建一张图片的调整大小的副本(在互联网上找到):
Bitmap ResizeImage(System.Drawing.Image image, int width, int height)
{
var destRect = new System.Drawing.Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
and I have this code, which first creates all the necessary directories to save pictures, and then starts changing all the images and saving them to new folders.我有这个代码,它首先创建所有必要的目录来保存图片,然后开始更改所有图像并将它们保存到新文件夹中。 In the process of executing the program, my memory starts to fill until it reaches the mark of ~ 590mb (~ 1800 images), and then throws an OutOfMemoryException error.
在执行程序的过程中,我的内存开始填满,直到达到~590mb(~1800张图像)的标记,然后抛出OutOfMemoryException错误。
void ResizeAllImages()
{
var files = Directory.GetFiles(ImagesDirectory, "*", SearchOption.AllDirectories);
if (!Directory.Exists(ResizedImagesDirectory)) Directory.CreateDirectory(ResizedImagesDirectory);
var dirs = Directory.GetDirectories(ImagesDirectory);
foreach(var d in dirs) Directory.CreateDirectory(System.IO.Path.Combine(ResizedImagesDirectory, System.IO.Path.GetFileName(d)));
foreach(var f in files)
{
using(var image = ResizeImage(System.Drawing.Image.FromFile(f), 224, 224))
{
var imgName = System.IO.Path.GetFileName(f);
var dirName = System.IO.Path.GetFileName(System.IO.Path.GetDirectoryName(f));
image.Save(System.IO.Path.Combine(ResizedImagesDirectory, dirName, imgName), ImageFormat.Png);
}
}
}
To solve this problem, I tried to add the following 2 lines of code to the foreach:为了解决这个问题,我尝试在foreach中添加以下两行代码:
GC.Collect();
GC.WaitForPendingFinalizers();
The profiler started to show that during the entire program operation the process takes ~ 50mb, however, when the previous mark of ~ 1800 images is reached, I get an OutOfMemoryException again.分析器开始显示,在整个程序运行过程中,该过程需要大约 50 mb,但是,当达到之前的大约 1800 张图像的标记时,我再次收到 OutOfMemoryException。 How can I solve this problem.
我怎么解决这个问题。 Thank you in advance
先感谢您
According to MSDN, the OutOfMemoryException
can be thrown in some non-intuitive situations.根据 MSDN,可以在一些非直观情况下抛出
OutOfMemoryException
。 For example, it can be thrown in the Bitmap.Clone
method:例如可以在
Bitmap.Clone
方法中抛出:
OutOfMemoryException: rect is outside of the source bitmap bounds.
OutOfMemoryException: rect 超出源位图边界。
We can see that you are not using the Clone method, however you are using a Rect and a Bitmap, and since the memory footprint of your program does not surpass 50MB, we can deduce that the problem is similar.我们可以看到您没有使用 Clone 方法,而是使用了 Rect 和 Bitmap,并且由于您的程序的内存占用不超过 50MB,我们可以推断出问题是相似的。
To really fix this problem, you should first isolate the problematic image, verify exactly what is happening, and then proceed accordingly.要真正解决此问题,您应该首先隔离有问题的图像,准确验证发生了什么,然后进行相应的操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.