28
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

PythonでPDFをまとめて画像に変換する

この記事でやりたいこと

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のコード

pdf2img.py
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形式で出力になります。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
28
Help us understand the problem. What are the problem?