【发布时间】:2015-03-21 18:58:46
【问题描述】:
这适用于在具有 32GB 内存的 64 位 Windows 8 系统上运行的 .NET 4.5 控制台应用程序。该应用程序面向 64 位平台并启用了 gcAllowVeryLargeObjects 标志,它允许应用程序创建大于 .NET 限制的 2Gb 的对象。所以,我可以创建一个 15GB 的整数数组。
我使用以下构造函数创建了一个 32,767 x 32,767 像素的 System.Windows.Media.Imaging.WriteableBitmap,它使用 WIC(Windows 成像组件而不是 GDI+,因为 WIC 可以处理比 GDI+ 更高的分辨率)
WriteableBitmap wbit = new WriteableBitmap(32767, 32767, 300, 300, PixelFormats.Bgra32, null);
我尝试使用以下代码将其保存为 JPG 格式
using (FileStream stream = new FileStream("c:\\test.jpg",FileMode.Create))
{
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(wbit));
encoder.Save(stream);
}
我也尝试使用以下代码将其保存为 PNG
using (FileStream stream = new FileStream("c:\\test.png",FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(wbit));
encoder.Save(stream);
}
对于 JPG 和 PNG,我可以将分辨率提高到 23,170 x 23,170,并且工作正常,但提高到 23,171 x 23,171 会引发以下异常
System.AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。在 MS.Wind32.PresentationCore.UnsafeNativeMethods.WICBitmapFrameEncode.WriteSource(SafeMILHandle THIS_PTR, SafeMILHandle pIBitmapSource, Int32Rect& r) 在 System.Windows.Media.Imaging.BitmapEncoder.Save(Stream 流)
有谁知道这个异常的原因,以及我如何能够绕过它,以便将完整的最大分辨率保存为 32,767 x 32,767?也许我必须使用另一个编码器,甚至开始寻找 .NET 框架之外的东西。理想情况下,我希望能够处理 JPEG 最大分辨率为 65,535 x 65,535 的图像,或者在 PNG 中以 100,000 x 100,000 像素甚至更高的分辨率处理图像。对于此事或朝着正确方向提出的建议,我将不胜感激。谢谢。
【问题讨论】:
-
"因为 WIC 可以处理比 GDI+ 更高的分辨率" 您从哪里发现的?我在文档中找不到任何关于此的内容。
-
@ScottChamberlain 没有关于这些的任何文档,它基于我过去几天对 Bitmap 和 WriteableBitmap 的测试。位图在“大约”22000 x 22000 像素处开始中断,这不是一个硬数字,因为它的限制基于 2GB 虚拟内存限制。因此,22000 x 22000 有时有效,有时无效。 WriteableBitmap 有一个硬限制,最高可达 32,767 x 32,767,但总是在 32,768 x 32,768 处中断。见this post
-
平铺不是一个选项? IE。 Google 地图也不是由一张巨大的图像组成的。
-
我已经做了平铺,然后再做,以便像 Goodle Maps 一样在网络上提供图像,但在那个阶段之前,我仍然需要生成单个 JPG 或 PNG 文件整件事。
-
我不是 Microsoft API 的专家,但错误中的“Wind32”位是可疑的。它表明编码器 API 正在调用 32 位非托管代码,然后该代码会落在您的大图像上。如果这是特定于编码器的,您可以在 System.Windows.Media 库中查找另一个编码器(BMP?)。或者,查找第三方 64 位编码器。 (System.Drawing.Bitmap.Save 会做得更好吗?)
标签: c# .net bitmap jpeg writeablebitmap