处理大量图片时内存不足异常
Out of Memory Exception when Processing Large Number of Images
我正在使用以下代码根据 EXIF 数据修复图像的方向
Image FixImageOrientation(Image srce)
{
const int ExifOrientationId = 0x112;
// Read orientation tag
if (!srce.PropertyIdList.Contains(ExifOrientationId)) return srce;
var prop = srce.GetPropertyItem(ExifOrientationId);
var orient = BitConverter.ToInt16(prop.Value, 0);
// Force value to 1
prop.Value = BitConverter.GetBytes((short)1);
srce.SetPropertyItem(prop);
// MessageBox.Show(orient.ToString());
// Rotate/flip image according to <orient>
switch (orient)
{
case 1:
srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
return srce;
case 2:
srce.RotateFlip(RotateFlipType.RotateNoneFlipX);
return srce;
case 3:
srce.RotateFlip(RotateFlipType.Rotate180FlipNone);
return srce;
case 4:
srce.RotateFlip(RotateFlipType.Rotate180FlipX);
return srce;
case 5:
srce.RotateFlip(RotateFlipType.Rotate90FlipX);
return srce;
case 6:
srce.RotateFlip(RotateFlipType.Rotate90FlipNone);
return srce;
case 7:
srce.RotateFlip(RotateFlipType.Rotate270FlipX);
return srce;
case 8:
srce.RotateFlip(RotateFlipType.Rotate270FlipNone);
return srce;
default:
srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
return srce;
}
}
我像这样处理一大批图像
for (x= 0; x<list.Count; x++)
{
filepath= list.ElementAt(x);
Bitmap image = new Bitmap(FixImageOrientation(Bitmap.FromFile(filepath)));
//Do long processing and at the end i do image.dispose();
image.dispose();
}
但是在处理大量图像时,我在
处遇到内存不足异常
Bitmap image = new Bitmap(FixImageOrientation(Bitmap.FromFile(filepath)));
为什么我得到这个..我猜我在循环结束时处理了这个图像。
在您的代码中,您创建了两个位图,但只处理了一个。
更改您的代码:
using(var source = Bitmap.FromFile(filepath)) {
using(var image = new Bitmap(FixImageOrientation(source))) {
// ... do long processing
}
}
这应该可以解决您的问题。
正如您可以在此答案中找到的那样 调用 dispose 并不一定会释放内存。这是垃圾收集器的任务。我假设您正在将图像快速加载到内存中。问题是,垃圾收集只是偶尔进行。如果您通过创建新对象使用大量内存,垃圾回收可能会因再次释放内存而变慢。
您可以尝试使用 GC.Collect() 从循环中直接调用它。
如果这还不够,您还可以尝试阻塞参数,它将暂停您的线程,直到 GC 运行 完成。
作为一种不同的方法,您可以将项目设置为编译为 x64,这将使您的程序能够访问超过 1GB 的内存。但使用此解决方案只会将问题推得更远。
托马斯
千条记录的FOR循环出现内存不足异常,可能的解决方案:
在您的程序中使用 using 语句来限制数据库对象的范围
使用后给列表赋空值
处理连接对象
我正在使用以下代码根据 EXIF 数据修复图像的方向
Image FixImageOrientation(Image srce)
{
const int ExifOrientationId = 0x112;
// Read orientation tag
if (!srce.PropertyIdList.Contains(ExifOrientationId)) return srce;
var prop = srce.GetPropertyItem(ExifOrientationId);
var orient = BitConverter.ToInt16(prop.Value, 0);
// Force value to 1
prop.Value = BitConverter.GetBytes((short)1);
srce.SetPropertyItem(prop);
// MessageBox.Show(orient.ToString());
// Rotate/flip image according to <orient>
switch (orient)
{
case 1:
srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
return srce;
case 2:
srce.RotateFlip(RotateFlipType.RotateNoneFlipX);
return srce;
case 3:
srce.RotateFlip(RotateFlipType.Rotate180FlipNone);
return srce;
case 4:
srce.RotateFlip(RotateFlipType.Rotate180FlipX);
return srce;
case 5:
srce.RotateFlip(RotateFlipType.Rotate90FlipX);
return srce;
case 6:
srce.RotateFlip(RotateFlipType.Rotate90FlipNone);
return srce;
case 7:
srce.RotateFlip(RotateFlipType.Rotate270FlipX);
return srce;
case 8:
srce.RotateFlip(RotateFlipType.Rotate270FlipNone);
return srce;
default:
srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
return srce;
}
}
我像这样处理一大批图像
for (x= 0; x<list.Count; x++)
{
filepath= list.ElementAt(x);
Bitmap image = new Bitmap(FixImageOrientation(Bitmap.FromFile(filepath)));
//Do long processing and at the end i do image.dispose();
image.dispose();
}
但是在处理大量图像时,我在
处遇到内存不足异常Bitmap image = new Bitmap(FixImageOrientation(Bitmap.FromFile(filepath)));
为什么我得到这个..我猜我在循环结束时处理了这个图像。
在您的代码中,您创建了两个位图,但只处理了一个。 更改您的代码:
using(var source = Bitmap.FromFile(filepath)) {
using(var image = new Bitmap(FixImageOrientation(source))) {
// ... do long processing
}
}
这应该可以解决您的问题。
正如您可以在此答案中找到的那样 调用 dispose 并不一定会释放内存。这是垃圾收集器的任务。我假设您正在将图像快速加载到内存中。问题是,垃圾收集只是偶尔进行。如果您通过创建新对象使用大量内存,垃圾回收可能会因再次释放内存而变慢。
您可以尝试使用 GC.Collect() 从循环中直接调用它。 如果这还不够,您还可以尝试阻塞参数,它将暂停您的线程,直到 GC 运行 完成。
作为一种不同的方法,您可以将项目设置为编译为 x64,这将使您的程序能够访问超过 1GB 的内存。但使用此解决方案只会将问题推得更远。
托马斯
千条记录的FOR循环出现内存不足异常,可能的解决方案:
在您的程序中使用 using 语句来限制数据库对象的范围
使用后给列表赋空值
处理连接对象