C# 如何在c语言中转换大型图像文件#

C# 如何在c语言中转换大型图像文件#,c#,C#,我有几个大的图像文件,我需要转换成不同的图像格式。我正在使用以下代码执行此操作: using (Image img =new Bitmap(inputImageName)) { img.Save(outputImageName, imageFormat); } 它可以进行对话,但由于图像很大,它会生成outofmemory异常。我读了几篇关于如何克服LOH碎片化的文章,但在本例中我无法使用其中任何一篇 我能做什么 图像大约为100字节,

我有几个大的图像文件,我需要转换成不同的图像格式。我正在使用以下代码执行此操作:

using (Image img =new Bitmap(inputImageName))
        {
            img.Save(outputImageName, imageFormat);
        } 
它可以进行对话,但由于图像很大,它会生成outofmemory异常。我读了几篇关于如何克服LOH碎片化的文章,但在本例中我无法使用其中任何一篇

我能做什么


图像大约为100字节,在打开3或4个图像后会发生这种情况。

这里需要问的问题是“我必须在.NET和/或C#中执行此操作吗?”

虽然我明白为什么对许多人来说,像C#这样灵活的语言可能是执行许多任务的答案,但我也不得不说,“当你只有一把锤子时,每个问题都像钉子。”

如果这是一次性转换,并且您只需要在一个项目中使用它们,那么我给您的建议是使用更适合此工作的独立工具

有很多付费应用程序,比如:

AcdSee照片管理器

释放工具,例如

Ifran视图及其图像转换功能

如果游戏中使用命令行脚本,请使用工具集,如ImageMagik:

Iamage Magik还具有.NET绑定,因此,如果项目需要在程序代码中动态转换这些绑定,则它的功能可以从.NET项目以及其他许多项目中使用


对于像这样的场景,确实没有理由重新发明轮子,这个问题已经解决了很多次了,这真的不是你必须做出的决定。

它与大对象堆没有任何关系。位图类是GDI+的托管包装器,GDI+是一大块非托管代码。它在非托管内存中分配像素数据缓冲区。代码使用的托管内存量非常小

100 MB的映像文件并不能说明需要多少非托管内存。它很可能是一种压缩图像格式,如JPEG或PNG。在解压后,它确实需要更多的非托管内存。因此,您很容易就需要数百兆字节

当您在32位操作系统上运行代码或选择x86作为EXE的平台目标设置(VS2010及以上版本的默认设置)时,这就是一个问题。您的程序从代码块和已加载的数据之间可用的孔中分配虚拟内存。GDI+需要一个连续的内存块来加载像素数据,当您的程序有很多可用的虚拟内存时,这可能很难实现,但它分布在许多孔中。另一个问题是地址空间碎片,加载DLL或分配内存可能会将一个大洞的大小一分为二


对于这个问题有一个简单的解决方案,在64位操作系统上运行代码。它有大量可用的虚拟内存,大洞。在32位操作系统上解决当前问题的可能性微乎其微。您无法直接控制内存管理器。

请查看WPF图像处理类,这些类不使用GDI。以下源代码是一个很好的起点:

public static void Resize(string input, string output)
{
    using (var inputStream = File.OpenRead(input))
    {
        var photoDecoder = BitmapDecoder.Create(inputStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);

        var frame = photoDecoder.Frames[0];

        using (var ouputStream = File.Create(output))
        {
            var targetEncoder = new PngBitmapEncoder();
            targetEncoder.Frames.Add(frame);
            targetEncoder.Save(ouputStream);
        }
    }    
}

你能详细说明一下吗?图像有多大?这会发生在一张图片上吗?十点以后?这和WPF有什么关系?事实上,您使用的库是用于WinForms的,而不是WPF。@KendallFrey:您是对的,这是winform库,但应用程序是WPF。如果在WPF中有更好的方法,那么我非常乐意使用WPF版本。