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
现在它可以只搜索并读出它需要的部分了。
当然,您可能无法控制图像格式的细节,但如果您这样做了,您会发现对于这种平铺图像操作,速度要快得多,而且需要的内存要少得多。
我正在尝试提取大型 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
:
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
现在它可以只搜索并读出它需要的部分了。
当然,您可能无法控制图像格式的细节,但如果您这样做了,您会发现对于这种平铺图像操作,速度要快得多,而且需要的内存要少得多。