裁剪大型 TIFF 图像 .NET,无需将图像读入内存
我正在尝试找出一种在 .NET 中裁剪大型 TIFF 图像的方法。具体来说,我尝试在 GeoTiff(一种允许将地理配准信息嵌入其自身的 TIFF)上执行此操作。对于那些不熟悉此类数据集的人来说,它完全符合 TIFF 6.0 并且通常大小很大;千兆字节范围内的许多倍。
我一直在摆弄 System.Windows.Media.Imaging 命名空间来尝试完成此任务。但是,要裁剪的 tiff 的大小会导致内存不足错误。谁能向我指出一些信息,显示如何在不一开始将输入图像读入内存的情况下裁剪图像?
仅供参考 - 我完全意识到 GDAL 完全有能力完成这项任务。然而,在不涉及不必要的细节的情况下,由于多种原因,目前无法选择使用我的应用程序部署 GDAL,因此我希望使用本机 .NET 类来实现此目的。但是,如果还有其他可以使用的第 3 方 .NET 库,我会洗耳恭听。
I am trying to figure out a way to crop large TIFF images in .NET. Specifically, I am trying to do this operation on a GeoTiff, a TIFF that allows georeferencing information to be embedded within itself. For those unfamiliar with this type of dataset, it is fully compliant with TIFF 6.0 and is usually huge in size; many times in the gigabyte range.
I've been messing around with the System.Windows.Media.Imaging namespace to try to accomplish this task. However, the size of the tiff to be cropped causes out of memory errors. Can anyone point me to some information showing how to crop an image without reading input image into memory at the onset?
FYI - I am fully aware that GDAL is more than capable for this task. However, without getting into unecessary details, deploying GDAL with my app is not an option at this point for several reasons, hence my desire to do this with native .NET classes. However, if there are other 3rd party .NET libraries that could be of use, I'm all ears.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看看 libtiff。您想通过扫描线(或通过条带,如果图像是这样格式化的)加载图像。显然,您仍然需要足够的内存来保存整个扫描线(或条带),但这比将整个图像加载到内存中更可行。
似乎有一个 .NET 版本的库,而且看起来像是免费且开源(与其他一些应用程序不同)。
Have a look at libtiff. You want to load the image by scanlines (or by strips, if that's how the image is formatted). Obviously, you still need enough memory to hold an entire scanline (or strip), but it's way more feasible than loading the entire image into memory.
There seems to be a .NET version of the library, and it looks like it's free and open source (unlike some of their other apps).
不幸的是,基于内置 GDI+ 的成像操作(在 System.Drawing 和 System.Drawing.Imaging 中可用)要求在某个时刻将完整图像加载到内存中。在你的情况下显然是不可行的。
Unfortunately, the built-in GDI+ based imaging operations (available within
System.Drawing
andSystem.Drawing.Imaging
require that the full image be loaded into memory at some point. This is obviously not feasible in your situation.您绝不能将千兆字节范围内的 TIFF 视为“图像”:将其视为磁盘上的文件或映射到内存中,并像数据集一样对其执行操作。
成像命名空间并不是为如此大的数据集而设计的,它是为了处理图片、较小的图像等而设计的。您必须找到 TIFF 操作库或编写自己的例程才能在文件级别工作。我过去曾使用过一个名为“libtiff”的基于 C 的开源库;这可能是一个很好的起点。
(您在编写自己的文件时会遇到一些困难,包括 TIFF 文件可以进行各种压缩 - 如果是岩土压缩,那么可能有标准/直接压缩,或者是未压缩的?在这种情况下,复制内存将是大部分工作- 如果您需要商业选项,我建议您查看 Atalasoft 的 DotImage 库。)
There's no way you should be considering a TIFF in the gigabyte range an 'image': treat it as a file on disk, or mapped into memory, and perform operations on it as if it were a dataset.
The Imaging Namespace isn't designed for such large datasets, it's for working with pictures, smaller images and so on. You'll have to either find a TIFF manipulation library or write your own routines to work at the file-level. There is an open-source C-based library called 'libtiff' I have worked with in the past; it could be a good starting point.
(Some difficulties you would face writing your own include the fact that TIFF files can have all kinds of compression - if it's geotechnical then maybe there's a standard / straightforward compression, or it's uncompressed? In which case copying memory around will be most of the work - that and preserving TIFF directories and entries. I would suggest taking a look at Atalasoft's DotImage library if you're after a commercial option.)