繁体   English   中英

如何在C#中转换大图像文件

[英]How to convert large image files in c#

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

using (Image img =new Bitmap(inputImageName))
        {
            img.Save(outputImageName, imageFormat);
        } 

它进行对话,而且由于图像很大,因此会生成内存不足的异常。 我读了几篇有关如何克服LOH碎片的文章,但是在这种情况下我无法使用它们。

我能做什么?

图像约为100MByte,它在打开3或4张图像后发生。

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

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

如果这是一次转换,而您只需要在一个项目中使用它们,那么我对您的建议是使用更适合Job的独立工具。

有大量的收费应用程序,例如:

AcdSee照片管理器

http://www.acdsee.com/

释放诸如

Ifran View及其图像转换功能

http://www.bleepingcomputer.com/forums/topic50519.html

如果您要玩命令行脚本,请使用诸如ImageMagik之类的工具集:

http://www.imagemagick.org/script/index.php

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

http://www.imagemagick.org/script/api.php

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

根据本文了解一下不使用GDI的WPF图像操作类。 以下源代码是一个很好的起点:

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);
        }
    }    
}

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

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

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

有一个简单的修复程序可以解决此问题,请在64位操作系统上运行代码。 它具有可用的虚拟内存块,而且有很大的漏洞。 对于32位操作系统上的当前问题,您可以采取任何措施的可能性很小。 您无法直接控制内存管理器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM