创建 15000 张图像的蒙太奇

Create a montage of 15000 images

我正在尝试使用 imagemagick 蒙太奇 collage/montage 创建 15000 张图像 command.The 工具非常适合一小部分图像,但是当尝试使用 15K 图像创建蒙太奇时,程序崩溃因为它不能只将 15K 图像加载到主内存中。 我认为在流中打开文件,然后以 100 个为一组堆叠是可行的,但如果有人有好的解决方案,那将会很有帮助。

在这里编写和测试任何东西都有点晚了,但我可能会这样做:

  • 生成一个文本文件,其中包含要剪辑的所有文件名
  • 使用 split 命令将其分成 100 个一组
  • 遍历所有组,从每个组中生成一行图像
  • 堆叠行

第一部分如下:

find . -name "*.jpg" -print > filelist.txt

下一部分是这样的:

split -l 100 filelist.txt ROWS

下一部分是这样的:

n=0
for f in ROWS* ; do
    magick @"$f" +append row${n}.jpg
    ((n=n+1))
done

最后一部分是这样的:

magick row*.jpg -append result.jpg

libvips 可以在不需要大量内存的情况下制作巨大的图像蒙太奇。例如:

$ vips arrayjoin "a.png b.png c.png d.png" output.png --across 2

这将读取四个 PNG 图像,将它们排成 2 x 2 网格的行,然后写入 out.png。您可以使用 $() 查找大量图像并按文件名排序,也许:

$ vips arrayjoin "$(ls *.jpeg | sort -t_ -k2g -k1g)" x.tif --across 20

这将加载文件名格式为 x_y.jpeg 的所有 JPEG 图像,按行和列对它们进行数字排序,然后 assemble 将它们放入 20 x N 的网格中。

15,000 张图片对于 linux 上的 command-line 来说太多了(你会从 bash 得到一个 Argument list too long 错误),但你可以从 python 和 pyvips。也许:

#!/usr/bin/python3

import sys
import glob
import pyvips

images = [pyvips.Image.new_from_file(filename, access="sequential")
          for filename in glob.glob(sys.argv[1] + "/*.jpg")]

joined = pyvips.Image.arrayjoin(images, across=100)

joined.write_to_file(sys.argv[2])

然后:

$ vips crop ~/pics/k2.jpg x.jpg 0 0 1000 1000
$ for i in {1..15000}; do cp x.jpg $i.jpg; done
$ VIPS_CONCURRENCY=1 /usr/bin/time -f %M:%e \
    ./arrayjoin.py . x.tif[compression=jpeg,tile]
4689264:78.38
$ vipsheader x.tif
x.tif: 100000x150000 uchar, 3 bands, srgb, tiffload

这就是将 15,000 张 1,000 x 1,000 像素的 JPG 图像组合成一个 100,000 x 150,000 像素的 JPEG-compressed TIFF。耗时80s,需要4.7gb的内存峰值