ImageMagick 的 Stream 无法读取 TIFF64?

ImageMagick's Stream can't read TIFF64?

我正在尝试提取大型 BigTIFF 图像 (TIFF64) 的子区域。如果图片不是太大,我可以convert src.tif dst.jpg。但是,如果图像真的很大,convert 不起作用。我试图使用 stream 来提取感兴趣的区域而不将完整的图像加载到内存中。但是,结果是一个 0 字节的文件。我在这里上传了我的一个 BigTIFF:

https://mfr.osf.io/render?url=https://osf.io/kgeqs/?action=download%26mode=render

这个足够小,可以与 convert 一起使用,并且它会使用 stream:

生成 0 字节图像

stream -map rgb -storage-type char '20-07-2017_RecognizedCode-10685.tif[1000x1000+10000+10000]' 1k-crop.dat

有没有办法让 stream 工作?这是 stream 中使用 TIFF64 的旧错误的卷土重来吗? http://imagemagick.org/discourse-server/viewtopic.php?t=22046

我正在使用 ImageMagick 6.9.2-4 Q16 x86_64 2016-03-17

我无法下载你的图像来做任何测试,但你可以考虑使用 vips,它非常快速且节省内存,特别是对于大图像 - 我认为你的是,否则你会可能不会使用 BigTIFF.

因此,如果我们使用 ImageMagick 制作一个 10,000 x 10,000 的大型 TIF 进行测试:

convert -size 10000x10000 gradient:cyan-magenta -compress lzw test.tif

我在这里展示了一个较小的 JPEG 版本:

你可以像这样用vips提取左上角,同时显示最大内存使用量(用--vips-leak):

vips crop test.tif a.jpg 0 0 100 100 --vips-leak

输出

memory: high-water mark 5.76 MB

你可以像这样提取右下角:

vips crop test.tif a.jpg 9000 9000 1000 1000 --vips-leak

输出

memory: high-water mark 517.01 MB

使用 ImageMagick,同样的操作需要 1.2GB 内存:

/usr/bin/time -l convert test.tif -crop 1000x1000+9000+9000 a.jpg
        2.46 real         2.00 user         0.45 sys
1216008192  maximum resident set size
         0  average shared memory size
         0  average unshared data size
         0  average unshared stack size
    298598  page reclaims

我同意 Mark 的出色回答,但我只想说,您使用的 TIFF 格式会产生很大的不同。

常规条带 TIFF 并不真正支持随机访问,但平铺 TIFF 支持。例如,这是一个 10k x 10k 像素条带 TIFF:

$ vips copy wtc.jpg wtc.tif
$ time vips crop wtc.tif x.tif 8000 8000 100 100 --vips-leak
real    0m0.323s
user    0m0.083s
sys     0m0.185s
memory: high-water mark 230.80 MB

这里的 TIFF reader 必须扫描几乎整个图像才能到达它需要的位,导致相对较高的内存使用。

如果您使用平铺图像重试:

$ vips copy wtc.jpg wtc.tif[tile]
$ time vips crop wtc.tif x.tif 8000 8000 100 100 --vips-leak
real    0m0.032s
user    0m0.017s
sys     0m0.014s
memory: high-water mark 254.39 KB

现在它可以只搜索并读出它需要的部分了。

当然,您可能无法控制图像格式的细节,但如果您这样做了,您会发现对于这种平铺图像操作,速度要快得多,而且需要的内存要少得多。