電算倶楽部 富山県のコンピュータ社会人サークル

富山県、特に滑川市、富山市、魚津市周辺で活動している社会人サークルです。

スキャンしたPDFの処理を考える その1 PDFを画像に変換

はじめに

引っ越しの際に買ったScanSnap S1500でPDFを作成していますが、PDFって閲覧できるソフトも限られるし、編集もしづらく扱いづらいです。 スキャンの仕方にもよるのですが、サイズも結構大きくなります。

スキャンしたPDFについて、うまいこと管理したく、次のことにチャレンジしてみます。

  1. OCRしてPDF内の検索を可能にする
  2. サイズを小さくする
  3. OCRしたテキストを検索可能にする

また、言語はPythonで作るのですが、裏テーマでなるべくPython用のライブラリを使わず、Windowsで使えるコマンドを使って実現します。 Python独自の部分を変更すれば、バッチやExcelなどからも使えるということになります。

処理のステップ

  1. PDFを画像に変換する
  2. 画像にOCR処理をかける
  3. 検索の仕組みを考える

必要コマンドのダウンロード

popplerをインストールします。 popplerはpdfを変換したり作成したりといった様々な事ができるコマンドの詰め合わせです。

インストールが終わったら、pdfimagesというコマンドが使えるようになっているはずです。 プロンプトで以下のコマンドで使い方を確認します。

pdfimages -h

以下のように出力されれば成功です。

pdfimages version 0.89.0
Copyright 2005-2020 The Poppler Developers - http://poppler.freedesktop.org
Copyright 1996-2011 Glyph & Cog, LLC
Usage: pdfimages [options] <PDF-file> <image-root>
  -f <int>       : first page to convert
  -l <int>       : last page to convert
  -png           : change the default output format to PNG
  -tiff          : change the default output format to TIFF
  -j             : write JPEG images as JPEG files
  -jp2           : write JPEG2000 images as JP2 files
  -jbig2         : write JBIG2 images as JBIG2 files
  -ccitt         : write CCITT images as CCITT files
  -all           : equivalent to -png -tiff -j -jp2 -jbig2 -ccitt
  -list          : print list of images instead of saving
  -upw <string>  : user password (for encrypted files)
  -p             : include page numbers in output file names
  -q             : don't print any messages or errors
  -v             : print copyright and version info
  -h             : print usage information
  -help          : print usage information
  --help         : print usage information
  -?             : print usage information

お試し

C:\ocr_srcフォルダに、PDFファイルscan.pdfが入っているとします。

f:id:s-densan:20210116191502p:plain

c:\ocr_dstに移動し、コマンドラインで以下のように打ち込みます。

pdfimages -png "C:\ocr_src\scan.pdf" out

同じフォルダに以下のファイルができます。(8ページの場合)

f:id:s-densan:20210116191756p:plain

プログラムを作る

import os
from typing import List, Dict
import glob


def main():
    # 入力ファイル
    src_pdf_path = r'C:\ocr_src\scan.pdf'
    # 出力ディレクトリ
    dst_dir = r'C:\ocr_dst'
    # 画像に変換してファイルリストを取得
    file_list = pdf2image(src_pdf_path, dst_dir)
    print(file_list)


def pdf2image(src_pdf_path: str, dst_path: str) -> List[str]:
    """
    PDFファイルを複数の画像にして保存する
    
    Parameters
    ----------
    src_pdf_path : str
        入力PDFファイルパス
    dst_path : str
        出力先フォルダパス
    
    Returns
    -------
    List[str]
        作成した画像のファイルパス
    """
    # プログラム名(必要ならばフルパスで指定)
    program = 'pdfimages'
    # 実行するコマンド
    command = f'{program} -png "{src_pdf_path}" out'

    # 入力PDFファイルが存在しない場合は終了
    if not os.path.isfile(src_pdf_path):
        return []

    # 出力先フォルダが存在しない場合は作成
    if not os.path.isdir(dst_path):
        if os.path.isfile(dst_path):
            return
        else:
            os.makedirs(dst_path)
    # 移行前のカレントディレクトリを変数に保持
    curdir_tmp = os.getcwd()
    # カレントディレクトリを変更
    os.chdir(dst_path)
    # コマンド実行
    os.system(command)
    # カレントディレクトリをもとに戻す
    os.chdir(curdir_tmp)

    file_list = glob.glob(os.path.join(dst_path, 'out-*.png'))
    return file_list


if __name__ == "__main__":
    main()

終わりに

今回はPDFをプログラムで画像ファイルに変換できるようにしました。 次は画像ファイルをOCR処理をかけ、文字情報を取り出します。