我需要创建和分割多页 TIFF 图像,大小从 2 页到近 100 页不等(A4、300 dpi、2500×3500 px)。该作业由 x64 Linux 服务器上的脚本定期执行。目前我使用的是 Imagemagick。较小的案例不会造成任何问题,但较大的案例会造成问题。
我需要大幅减少操作期间使用的内存量。
例如:
convert *.jpg -compress lzw output.tif
(70 个 jpeg 文件)消耗大约 4.6 GB 的 RAM,尽管每个输入小于 2MB,但生成的文件也小于 250MB。
逆向操作:
convert input.tif output-%04d.png
有类似的问题。
据我所知,发生这种情况是因为 Imagemagick 首先加载并解码所有输入图像,然后才开始将它们编码到输出文件中。
如何创建和分割多页 TIFF 图像而不占用如此大的内存空间?我不一定非要使用 ImageMagick,任何其他免费工具都可以。
答案1
今天,在尝试分割 1700 张图像、1G tif 文件时,我遇到了同样的问题。16G 内存不够,然后尝试将其缓存在磁盘上,但速度很慢,并且很容易耗尽硬盘上的 100G 多空间而没有任何结果(这可能是一个错误)。
但显然 ImageMagick 可以从原始文件中提取特定的 tif 而无需完全加载它,因此能够使用简单的 bash 脚本拆分更大的文件:
subfiles=$(identify -quiet -format '%n\n' largefile.tif | head -n1)
for (( i = 0; i < subfiles; i++ )); do
convert largefile.tif[$i] -scene 1 split/smallerfile_$i.tif
done
虽然不知道如何在不耗尽内存的情况下创建一个大文件,所以这也许只是一半的答案?
答案2
我发现@tarikki 的答案是最好的答案之一,因为它确实不会挂起服务器,也不会占用内存和磁盘空间,而且速度很快。
对我有帮助的一些改进:
replace END=2000 by END=$(identify -format "%n" largefile.tif)
- TIF 索引从 0 开始,因此循环应从 开始,
0
并使用<
而不是<= : for((i=0;i<END;i++))
答案3
ImageMagick
您可以使用适用于 Windows 的最新版本和以下脚本通过 PowerShell 对整个 TIFF 文件夹执行此操作:
$Files = Get-ChildItem
mkdir split
$Files | ForEach-Object {
$PageCount = (magick identify -format '%n' $_.Name).length
for ($i = 0; $i -lt $PageCount; $i++) {
$Name = $_.Name + "[" + $i + "]"
$OutputName = "split\" + $_.Name.Split(".")[-2] + "-" + $i + ".tif"
magick convert $Name -scene 1 $OutputName
}
}
答案4
tiffcp可用于创建多页 tiff,如下所示:
tiffcp *.tif out.tif