在不读入图像到内存的情况下,使用.NET裁剪大型TIFF图像。

4
我正在尝试找到一种在.NET中裁剪大型TIFF图像的方法。具体来说,我正在尝试对GeoTiff进行此操作,这是一种允许嵌入地理参考信息的TIFF格式。对于不熟悉此类数据集的人来说,它完全符合TIFF 6.0标准,通常非常巨大,达到几个GB的大小。
我一直在尝试使用System.Windows.Media.Imaging命名空间来完成此任务。然而,要裁剪的tiff文件大小会导致内存不足错误。有没有人可以指导我如何在不读取输入图像的情况下裁剪图像?
FYI-我完全意识到GDAL能够胜任此任务。但是,不必要地详细介绍,目前在我的应用程序中部署GDAL不是一个选项,因此我希望使用本机.NET类来完成此操作。但是,如果有其他第三方.NET库可供使用,我会听取建议。

我按照这个答案解决了我的问题。 - Cryeyes
3个回答

3
请查看libtiff。您想按扫描线(如果图像格式化为条带,则按条带)加载图像。显然,您仍需要足够的内存来容纳整个扫描线(或条带),但这比将整个图像加载到内存中要可行得多。
似乎有一个.NET版本的库,看起来它是免费和开源的(不像他们的其他应用程序)。

另外,请注意,一些TIFF图像使用基于瓦片的编码,对于非常大尺寸的图像比条带更有效,因为只有一个瓦片的内容可以被解码,而不是整个条带。Libtiff使得在条带和瓦片级别上工作相当容易,但即便如此,对TIFF容器结构的一些了解也是有好处的。请参阅TIFF 6.0规范 - allonym

1

不幸的是,基于GDI+的内置图像操作(在System.DrawingSystem.Drawing.Imaging中可用)需要在某个时刻将整个图像加载到内存中。显然,在您的情况下这是不可行的。


1

你绝不能将大小在千兆字节范围内的TIFF视为“图像”:把它当作一个磁盘上的文件,或者映射到内存中,并像对待数据集一样对其执行操作。

Imaging命名空间并不适用于如此大的数据集,它是用于处理图片、较小的图像等。你必须要找到一个TIFF处理库,或者编写自己的例程来处理文件。过去我曾经使用过一个叫做“libtiff”的开源C库,可以作为一个很好的起点。

(如果要自己编写程序的话,你会遇到一些困难,比如TIFF文件可能有各种压缩方式——如果是地质数据的话,也许有标准/简单的压缩方式,或者是未压缩的?那么复制内存可能会成为主要工作——除此之外还要保留TIFF目录和条目。如果你想使用商业选项的话,我建议看看Atalasoft的DotImage库。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接