Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 处理大量图像时出现内存不足异常_C#_.net_Bitmap_Out Of Memory_Gdi+ - Fatal编程技术网

C# 处理大量图像时出现内存不足异常

C# 处理大量图像时出现内存不足异常,c#,.net,bitmap,out-of-memory,gdi+,C#,.net,Bitmap,Out Of Memory,Gdi+,Im使用以下代码根据EXIF数据修复图像的方向 Image FixImageOrientation(Image srce) { const int ExifOrientationId = 0x112; // Read orientation tag if (!srce.PropertyIdList.Contains(ExifOrientationId)) return srce; v

Im使用以下代码根据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;
            }
        }

为什么我会得到这个。。我想我会在循环结束时处理此图像。

在代码中创建两个位图,但只处理一个。 更改您的代码:

using(var source = Bitmap.FromFile(filepath)) {
    using(var image = new Bitmap(FixImageOrientation(source))) {
       // ... do long processing
    }
}

这将解决您的问题。

在代码中创建两个位图,但只处理一个。 更改您的代码:

using(var source = Bitmap.FromFile(filepath)) {
    using(var image = new Bitmap(FixImageOrientation(source))) {
       // ... do long processing
    }
}

这应该可以解决您的问题。

您可以在这个答案中找到,调用dispose并不一定会释放内存。这是垃圾收集器的任务。我假设,您正在相当快地将图像加载到内存中。问题是,垃圾收集只是偶尔进行。如果您通过创建新对象来使用大量内存,垃圾收集可能会因为再次释放内存而变慢

您可以尝试使用GC.Collect()从循环中直接调用它。 如果这还不够,还可以尝试blocking参数,它将暂停线程,直到GC运行完成

作为一种不同的方法,您可以将项目设置为x64编译,这将使您的程序能够访问超过1GB的内存。但有了这个解决方案,你只会把问题推得更远


Thomas

正如您在本回答中所发现的,调用dispose并不一定会释放内存。这是垃圾收集器的任务。我假设,您正在相当快地将图像加载到内存中。问题是,垃圾收集只是偶尔进行。如果您通过创建新对象来使用大量内存,垃圾收集可能会因为再次释放内存而变慢

您可以尝试使用GC.Collect()从循环中直接调用它。 如果这还不够,还可以尝试blocking参数,它将暂停线程,直到GC运行完成

作为一种不同的方法,您可以将项目设置为x64编译,这将使您的程序能够访问超过1GB的内存。但有了这个解决方案,你只会把问题推得更远


托马斯

在记录的千次循环中出现内存不足异常,一种可能的解决方案:

  • 在程序中使用using语句来限制数据库对象的范围

  • 使用后为列表分配空值

  • 处理连接对象


  • 千条记录的FOR循环内存不足异常,一种可能的解决方案:

  • 在程序中使用using语句来限制数据库对象的范围

  • 使用后为列表分配空值

  • 处理连接对象


  • 您正在创建两个图像,并且仅处理一个
    位图。FromFile(filepath)
    新位图(
    )。这样,在运行程序时打开windows任务管理。如果您看到内存快速增加,则表明某个地方内存泄漏,您正在创建两个图像,并且仅处理一个
    位图.FromFile(filepath)
    新建位图(
    .Ghetto方式,在运行程序时打开windows任务管理。如果您看到内存快速增长,则表示内存在某处泄漏,谢谢..因为图像是全局对象..我想我可以简单地使用
    使用(var source=Bitmap.FromFile(filepath)){位图图像=新建位图(fixamageorientation(source));}
    并使用
    image.dispose()关闭
    image
    。这样行吗?@techno抱歉,我不明白你的意思。你必须处理两个位图。我的意思是..我在代码中分配
    image
    对象。如果我使用
    use
    语句处理
    image
    ,我就不能这样做,所以我只是使用(var source=Bitmap.FromFile(filepath))使用
    {
    并从
    源代码创建
    图像
    并手动处理
    图像
    对象…而不是使用
    语句使用第二个
    对象。我无法自..无法为使用
    语句创建的对象赋值。为什么需要重新分配
    图像
    对象?谢谢..因为image是一个全局对象。我想我可以简单地使用
    使用(var source=Bitmap.FromFile(filepath)){Bitmap image=new Bitmap(fixmageorientation(source));}
    和dispose off
    image
    使用
    image.dispose()
    。这样行吗?@techno抱歉,我不明白你的意思。你必须处理两个位图。我的意思是..我在代码中分配
    image
    对象。如果我使用
    use
    语句处理
    image
    ,我就不能这样做,所以我只是使用(var source=Bitmap.FromFile(filepath))使用
    {
    并从
    源代码创建
    图像
    并手动处理
    图像
    对象…而不是使用
    语句使用第二个
    对象。我无法从..开始为使用
    语句创建的对象赋值。为什么需要重新赋值
    图像
    using(var source = Bitmap.FromFile(filepath)) {
        using(var image = new Bitmap(FixImageOrientation(source))) {
           // ... do long processing
        }
    }