上位システムからPDFで伝票をもらうのですが、その全ページについて指定部分でトリミングを行い、再度PDFで保存したいときに。
Windows環境でのメモ。Python pillow でコードを書かずともMakefileのみで、やればできるもんです。
事前準備
以下のツールをインストールしておきます。
- ImageMagick - https://imagemagick.org/script/download.php
- xpdftools (pdf2pngが含まれる) - https://qiita.com/wutai00/items/28b8930a617034687909
- pdftk - https://pdftk.en.softonic.com/
Makefileでは、以下のような定数を定義するとします。
PDF2PNG = d:\opt\xpdftools\bin32\pdftopng.exe
IMGMGK = d:\opt\magick\convert.exe
IMGMTG = d:\opt\magick\montage.exe
PDFTK = d:\opt\pdftk\bin\pdftk.exe
やってみる
PDFファイルを画像にする
$(PDF2PNG) -gray -r 600 source.pdf output.png
- -r 600 は出力させたい解像度。数字を大きくするほど繊細で大きな画像になります。
出力した画像から、欲しい範囲をトリミング
$(IMGMGK) -crop 1000x520+320+610 -quality 80 input.png clip__.bmp
- x=320, y=610 を始点として、(1000x520)の範囲をトリミング
画像の周囲にマージン枠を付ける(キャンバスを拡大)
$(IMGMGK) -gravity center -background white -extent 1400x700 input.bmp output.bmp
- gravityはセンタリングポジションを指定します。centerだと上下左右センターに配置されます。
- extent は、最終的に出力を希望するビットマップサイズです。
画像をPDFに戻す
$(IMGMGK) -quality 80 source.bmp output.pdf
- pngファイルをソースにpdfを作ると、解像度関連で面倒なことになるので、bmpファイルを使うのが無難です。
作成した複数のPDFデータを連結
pdftkを呼びます。
$(PDFTK) source*.pdf cat output merge.pdf
これら全部を合体させると
以下のようなMakefileが出来上がります。
TARGET_SRC = $(wildcard input*.pdf)
all:
make pdf2png
make clip
make clip2pdf
make concatpdf
pdf2png:
$(PDF2PNG) -gray -r 600 $(TARGET_SRC) input.png
clip:
-del clip__*
for %%I in (input*.png) do ( $(IMGMGK) -crop 1000x520+320+610 -quality 80 "%%~nI.png" "clip__%%~nI.bmp" )
clip2pdf:
for %%I in (clip__*.bmp) do ( $(IMGMGK) -gravity north -background white -extent 1400x700 -quality 90 "%%~nI.bmp" "%%~nI.pdf" )
concatpdf:
$(PDFTK) clip__*.pdf cat output merge.pdf
PDFで、1 枚の用紙に複数のページを印刷する(n-up)
古典的には psmulti, pdfjam のようなツールを使うのが定石ですが、Windowsではlibpaperを入れるのが面倒なので。以下の手順でやっちゃう。
- pdfを画像データに変換 (pdftopng) https://qiita.com/wutai00/items/28b8930a617034687909
- ImageMagickのmontage.exeを使い、画像を連結する https://imagemagick.org/Usage/montage
nup:
$(PDF2PNG) input.pdf clips.png
$(IMGMTG) -tile 2x2 -geometry +100+100 clips*.png output.pdf
縦に2ページ、横に2ページ分を割り付け、マージンは100px100pxで確保しています。
あとがき
- コマンドラインでPDFデータをプリンタに送って印刷することもできる。 https://qiita.com/wutai00/items/22228a94524f432be276