この記事でやりたいこと
PDFファイルを1ページ1ファイルで画像(PNG)に変換します。
業務用帳票出力の検証作業前処理を想定しているので複数のPDFファイルをまとめて処理できるようにしました。
準備するもの
- Python3が動く環境。この記事ではPython3.8.1(Windows 64bit)を使っています
- Poppler。PDFを操作できるオープンソースのコマンドラインツール群
- pdf2image。PopplerをPythonから使えるようにするラッパーモジュール
Popplerのインストール
本家(ソース)
https://poppler.freedesktop.org/
Windows用のバイナリがこちらで公開されています。
http://blog.alivate.com.au/poppler-windows/
インストール手順についてはこちらのサイトにまとまっています。
http://pdf-file.nnn2.com/?p=863
説明後半にある言語ファイルを入れておかないと日本語のファイル名が化け化けになるので忘れずに入れておきましょう。
2020年1月6日追記
imread()やimwrite()がascii以外のファイル名を扱えないので、openCV-Pythonを使って後処理をするときはファイル名をascii文字に変える必要があります。
base = urllib.parse.quote(pdf_file.stem)
みたいな感じでURLエンコードしちゃってもいいけど人が読めないですね。
元データの改名が難しいときは、こういう対応方法もあります。
Python OpenCV の cv2.imread 及び cv2.imwrite で日本語を含むファイルパスを取り扱う際の問題への対処について
https://qiita.com/SKYS/items/cbde3775e2143cad745
pdf2imageのインストール
pip install pdf2image
Githubはこちら
https://github.com/Belval/pdf2image
Pythonのコード
import pathlib
import pdf2image
pdf_files = pathlib.Path('in_pdf').glob('*.pdf')
img_dir = pathlib.Path('out_img')
for pdf_file in pdf_files:
base = pdf_file.stem
images = pdf2image.convert_from_path(pdf_file, grayscale=True, size=640)
for index, image in enumerate(images):
image.save(img_dir/pathlib.Path(base + '-{}.png'.format(index + 1)),
'png')
やっていることは単純で、カレントディレクトリのin_pdfフォルダにあるPDFファイルを読み込んで、out_imgフォルダに{PDFのファイル名}-{ページ}.pngを出力しています。
例)なにかの帳票.pdf → なにかの帳票-1.png なにかの帳票-2.png
画像変換のパラメータは
images = pdf2image.convert_from_path(pdf_file, grayscale=True, size=640)
のところで設定できます。
-
grayscale=True
でグレースケール。grayscale=False
にするか指定を略するとカラー -
size=n
でnピクセル四方に収まるように出力。指定がなければDPI値で計算したサイズ -
dpi=n
でDPI値指定(既定値は200DPI)。サイズ指定があるときはそちらが優先
ほかにもいろいろ設定できますがとりあえずこれだけでも十分でしょう。
画像フォーマットは
image.save(img_dir/pathlib.Path(base + '-{}.png'.format(index + 1)), 'png')
のところを
image.save(img_dir/pathlib.Path(base + '-{}.jpg'.format(index + 1)), 'jpeg')
とするとJPEG形式で出力になります。