写大tiff图片

时间:2016-03-03 10:18:37

标签: c++ gdal libtiff

我正在用bigtif库编写大的tiff文件。我使用简单的“TIFFWriteScanline”调用来编写tiff并正确地写入数据,直到文件大小超过3,4 GB,并且写入过程变得非常慢但正确写入tiff)。我想要一种解决方法,因为它会导致我的应用程序速度瓶颈。我可以在libtiff中解决这个问题,或者我必须切换到另一个库,如gdal,..?

gdal可以用很快的速度写出巨大的tiff文件(超过4GB)吗?

提前感谢。

2 个答案:

答案 0 :(得分:2)

GDAL可以编写非常大的BigTIFF。您需要使用BigTIFF支持构建GDAL。

如果从GDAL外部构建libTIFF,则需要使用libTIFF版本4或更高版本。

您需要将一组选项传递给GDAL才能编写BigTIFF,请参阅:

http://www.gdal.org/frmt_gtiff.html

  • BIGTIFF = YES / NO / IF_NEEDED / IF_SAFER:控制创建的文件是BigTIFF还是经典TIFF。

您可以使用以下选项加快处理速度:

  • NUM_THREADS = number_of_threads / ALL_CPUS :(来自GDAL 2.1)通过指定工作线程数启用多线程压缩。值得缓慢按压,如DEFLATE或LZMA。 JPEG将被忽略。默认是主线程中的压缩。

如果您自己编写BigTIFF,那么当您打开TIFF文件进行编写时,您需要通过' 8' (作为ASCII)到TIFFOpen调用作为模式字符串的一部分。

tif_open.c中的文档指出了有效选项:

/*
 * Process library-specific flags in the open mode string.
 * The following flags may be used to control intrinsic library
 * behaviour that may or may not be desirable (usually for
 * compatibility with some application that claims to support
 * TIFF but only supports some brain dead idea of what the
 * vendor thinks TIFF is):
 *
 * 'l' use little-endian byte order for creating a file
 * 'b' use big-endian byte order for creating a file
 * 'L' read/write information using LSB2MSB bit order
 * 'B' read/write information using MSB2LSB bit order
 * 'H' read/write information using host bit order
 * 'M' enable use of memory-mapped files when supported
 * 'm' disable use of memory-mapped files
 * 'C' enable strip chopping support when reading
 * 'c' disable strip chopping support
 * 'h' read TIFF header only, do not load the first IFD
 * '4' ClassicTIFF for creating a file (default)
 * '8' BigTIFF for creating a file
 *
 * The use of the 'l' and 'b' flags is strongly discouraged.
 * These flags are provided solely because numerous vendors,
 * typically on the PC, do not correctly support TIFF; they
 * only support the Intel little-endian byte order.  This
 * support is not configured by default because it supports
 * the violation of the TIFF spec that says that readers *MUST*
 * support both byte orders.  It is strongly recommended that
 * you not use this feature except to deal with busted apps
 * that write invalid TIFF.  And even in those cases you should
 * bang on the vendors to fix their software.
 *
 * The 'L', 'B', and 'H' flags are intended for applications
 * that can optimize operations on data by using a particular
 * bit order.  By default the library returns data in MSB2LSB
 * bit order for compatibility with older versions of this
 * library.  Returning data in the bit order of the native CPU
 * makes the most sense but also requires applications to check
 * the value of the FillOrder tag; something they probably do
 * not do right now.
 *
 * The 'M' and 'm' flags are provided because some virtual memory
 * systems exhibit poor behaviour when large images are mapped.
 * These options permit clients to control the use of memory-mapped
 * files on a per-file basis.
 *
 * The 'C' and 'c' flags are provided because the library support
 * for chopping up large strips into multiple smaller strips is not
 * application-transparent and as such can cause problems.  The 'c'
 * option permits applications that only want to look at the tags,
 * for example, to get the unadulterated TIFF tag information.
 */

确保将tiff作为条带或瓷砖写出来。我喜欢瓷砖。使用GDAL时也是如此。对于BigTIFF图像,您必须将图像处理为图块或条带。

编辑18/19 24/7/2017

我回答这个问题的原因是因为我不得不为一个客户创建巨大的金字塔GeoTIFF(11个级别可能覆盖整个世界)。

到目前为止,我创建的最大图像仅略低于4GB。我刚刚将最高分辨率图像的尺寸增加了四倍(到1638400x1638400像素RGBA,LZW压缩)。到目前为止已经过了一个小时,我只生成了这一层的5%(在MSI GP727RD Leopard'发布版本上)。

时间问题很复杂,因为我正在将矢量数据绘制到正在生成的每个图块中。

我部分使用GDAL从坐标系WKT创建GeoTIFF标签(不得不将其从驱动程序中删除)。

我正在使用libTIFF写出TIFF my-self。一旦完成所有工作,我将把处理推送到尽可能多的线程中。然而,我将为每个线程创建单独的GeoTIFF,因为没有简单的方法将该批次组合成一个大的TIFF,并且我不确定这在任何情况下都是明智的。

32位进程中的内存使用率非常低。我的过程使用~60Mb的内存。

答案 1 :(得分:1)

这是使用LibTIFF库编写bigTIFF的一个很好的例子:

TIFF *tif = TIFFOpen(fileName, "w8");

来源和背景:https://gist.github.com/jcupitt/ba60e4e1100607d7a5cc9c19e2ec11e8