C# .NET Bitmap 的最大分辨率是多少? [英] What is the maximum resolution of C# .NET Bitmap?

查看:22
本文介绍了C# .NET Bitmap 的最大分辨率是多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

理论上,如果您有足够的内存,则应该是 65,535 x 65,535,大约 17GB.

Theoretically, it should be 65,535 x 65,535 given you have enough memory, about 17GB.

然而,创建一个 .NET 4.5 控制台应用程序来测试它,它抛出 System.ArgumentException: Parameter is not valid.

However, creating a .NET 4.5 Console Application to test it out, it throws System.ArgumentException: Parameter is not valid.

该应用程序是为 64 位平台构建的.在 64 位平台上运行,内存为 32GB.我能够获得的最大分辨率是 22,000 x 22,000 像素.

The application is built for 64bit platform. Running on 64bit platform with 32GB of memory. Maximum resolution I've been able to get is 22,000 x 22,000 pixels.

我找不到任何关于此的文档.

I could not find any documentation on this.

奇怪的行为是,即使是 22,000 x 22,000 像素,它也并不总是有效.它有时有效,有时会抛出异常.这让我觉得它与连续内存分配有关,但大约有 30GB 的空闲内存.

And odd behavior is that even at 22,000 x 22,000 pixels, it doesn't always work. It sometimes works, and it sometimes throws the exception. This make me think it's related to contiguous memory allocation, but there is about 30GB of free memory.

有人有这方面的经验吗?如果我想使用 100,000 x 100,000 像素或更大的图像,除了实现我自己的位图之外,最好的方法是什么?

Does anybody have any experience with this? And if I wanted to work with say, 100,000 x 100,000 pixel image and larger, what would be the best way besides implementing my own bitmap?

问题不在于 .NET 最大对象大小.这可以通过针对 64 位平台并在应用程序配置中设置 gcAllowVeryLargeObjects 标志来克服.通过这种方式,我可以让应用程序使用单个整数数组消耗超过 15GB 的内存.到目前为止,答案似乎在于 GDI+ 的底层实现,但我该如何绕过它?

The problem isn't .NET Maximum Object Size. This can be overcome by targeting for 64bit platforms, and setting the gcAllowVeryLargeObjects flag in the application config. In this way, I can get the application to consume over 15GB of memory with a single array of integers. So far, the answer seems to lie in the underlying implementation of the GDI+, but how do I get around it?

推荐答案

这是 Windows 强加的 GDI+ 限制.GDI+ 为位图的像素数据创建内存映射文件视图.这使得它非常高效,位图往往很大,并且 MMF 有助于将像素数据保留在分页文件之外.RAM 页面可以简单地丢弃并从文件中重新读取.同样臭名昭著的是,许多程序员看到他们的 Save() 调用失败,并在他们忘记处理旧位图时出现奇怪的异常.

This is a GDI+ limitation imposed by Windows. GDI+ creates a memory-mapped file view for the pixel data of the bitmap. That makes it very efficient, bitmaps tend to be large and the MMF helps to keep the pixel data out of the paging file. RAM pages can simply be discarded and re-read from the file. Also rather notorious, lots of programmers have seen their Save() call fail with a wonky exception when they forgot to dispose the old bitmap.

Windows 限制 MMF 上的视图可以有多大,换句话说,文件中可以直接寻址的数据量,如 这篇 MSDN 文章:

Windows restricts how large the view on an MMF can be, in other words the amount of data in the file that can be directly addressed, as documented in this MSDN article:

由命名文件支持的文件映射对象的大小受磁盘空间限制.文件视图的大小限于未保留虚拟内存的最大可用连续块.这最多是 2 GB 减去进程已经保留的虚拟内存.

The size of a file mapping object that is backed by a named file is limited by disk space. The size of a file view is limited to the largest available contiguous block of unreserved virtual memory. This is at most 2 GB minus the virtual memory already reserved by the process.

最大可用连续块"是 32 位进程中的限制,往往徘徊在约 600 MB 左右,给予或接受.2 GB 限制在 64 位进程中生效.从技术上讲,GDI+ 可以通过重新映射视图来绕过这个限制.但事实并非如此,LockBits() 方法(也在内部大量使用)效率低下且使用起来非常尴尬.

"Largest available continuous block" is the restriction in a 32-bit process, tends to hover around ~600 MB, give or take. The 2 GB limit kicks in on a 64-bit process. Technically GDI+ could bypass this limit by remapping the view. But it doesn't, the LockBits() method (also heavily used internally) would be inefficient and very awkward to use.

要使用更大的位图,您需要移至 GDI+ 的后继者 WIC (Windows 成像组件).通过 System.Windows.Media.Imaging 命名空间在 .NET 中公开.

To use larger bitmaps you need to move to the successor of GDI+, WIC (Windows Imaging Component). Exposed in .NET through the System.Windows.Media.Imaging namespace.

这篇关于C# .NET Bitmap 的最大分辨率是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆