jpeg 画像群を PDF ファイルに変換(ImageMagick, imgpdf)

先日国立国会図書館デジタルコレクションの蔵書の画像をダウンロードして余白をカットして読みやすくしました．jpeg を zip アーカイブにまとめたのですが，PDF ファイルのほうが都合がいいことも．ということで jpeg ファイル群を PDF ファイルに変換しました．

国立国会図書館デジタルコレクションの蔵書の画像の余白を削除して読みやすくする – matoken’s meme

ImageMagick の convert コマンドを使うとメモリ不足で失敗，ポリシーファイルの /etc/ImageMagick-6/policy.xml でメモリリソースを 1GB から 4GB に設定しても失敗して8GB に設定してやっと処理が出来ました．

$ convert 2530201/* 宇宙船ビーグル号の冒険.pdf (1)
:
convert-im6.q16: cache resources exhausted `2530201/2530201-107.jpg' @ error/cache.c/OpenPixelCache/4119.
convert-im6.q16: TooManyExceptions (exception processing is suspended) @ warning/exception.c/ThrowException/1054.
convert-im6.q16: cache resources exhausted `2530201/2530201-108.jpg' @ error/cache.c/OpenPixelCache/4119.
$ identify -list resource (2)
Resource limits:
Width: 32KP
Height: 32KP
List length: unlimited
Area: 256MP
Memory: 1GiB
Map: 2GiB
Disk: 2GiB
File: 768
Thread: 4
Throttle: 0
Time: unlimited
$ identify -limit memory 4096MiB -list resource | grep ^\ \ Memory: (3)
Memory: 1GiB
$ identify -limit memory 512MiB -list resource | grep ^\ \ Memory: (4)
Memory: 512MiB
$ sudo git -C /etc diff /etc/ImageMagick-6/policy.xml (5)
diff --git a/ImageMagick-6/policy.xml b/ImageMagick-6/policy.xml
index 4b878ce..aa54cbe 100644
--- a/ImageMagick-6/policy.xml
+++ b/ImageMagick-6/policy.xml
@@ -95,7 +95,7 @@
<!-- Set maximum amount of memory in bytes to allocate for the pixel cache
from the heap. When this limit is exceeded, the image pixels are cached
to memory-mapped disk. -->
- <policy domain="resource" name="memory" value="1024MiB"/>
+ <policy domain="resource" name="memory" value="4096MiB"/>
<!-- Set maximum amount of memory map in bytes to allocate for the pixel
cache. When this limit is exceeded, the image pixels are cached to
disk. -->
$ identify -list resource | grep ^\ \ Memory: (6)
Memory: 4GiB

ImageMagick の convert コマンドで PDF ファイルに変換したが途中で失敗

ImageMagick の リソースを確認

limit memory で大きくは出来ない

limit memory で小さくは出来る

ImageMagick のポリシーファイルを編集してメモリ利用可能量を増やした

メモリ利用可能量が増えたのを確認

いちおうこれで返還でしましたが，このメモリ利用量と変換時間は大きすぎるので他の方法を探しました．

img2pdf というコマンドを見つけました．このコマンドは可能ならロスレスで画像を PDF ファイルに変換してくれるので高速(かつ省リソースなはず)で処理できそうです．

josch/img2pdf – img2pdf – Muffin Gitea

導入はディストリビューションパッケージから．実行速度もとても早かったです．

$ sudo apt install img2pdf (1)
$ img2pdf -o 宇宙船ビーグル号の冒険-img2pdf.pdf 2530201/* (2)
find 2530201 -type f -print0 | sort -Vz | xargs -0 img2pdf -o 宇宙船ビーグル号の冒険.pdf (3)

img2pdf パッケージを導入

PDF に変換

画像ファイル名で並べ替えて標準入力から画像ファイルリストを渡し，PDF ファイルに

変換時間の比較です．convert が異様に遅いですが，これはスワップを使ってしまっているのも大きいと思われ，メモリの大きいマシンだともっと早くなると思います．

$ time convert 2530201/* 宇宙船ビーグル号の冒険.pdf

real 5m18.636s
user 0m47.748s
sys 0m31.136s
$ time img2pdf -o 宇宙船ビーグル号の冒険-img2pdf.pdf 2530201/*

real 0m1.279s
user 0m0.556s
sys 0m0.180s

実際の画像も特に問題なさそうだし，ファイルサイズもほとんど変わりませんでした．

単純に画像を PDF ファイルに変換する時は img2pdf コマンドを使うのが良さそうです．

環境

$ dpkg-query -W imagemagick img2pdf
imagemagick 8:6.9.12.98+dfsg1-5.2
img2pdf 0.5.1-1
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux trixie/sid
Release: n/a
Codename: trixie
$ arch
x86_64