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版本。