自炊でスキャンしたPDFを「テキスト検索できるPDF」に変換したい——この記事ではそのための手順を解説します。

処理の流れは次のとおりです。

自炊PDF → pdftoppm → PNG画像(ページ毎)→ tesseract → テキスト埋め込みPDF(ページ毎)→ pdfunite → 完成PDF

この記事では tesseract を使って手動で処理します。tesseract はOCRエンジン単体のため、PDFをいったんページごとの画像に変換してからOCRをかけ、再度PDFに結合するという手順を取ります。

tesseract(OCR)

はじめに、画像データから文字を認識してPDF化するtesseract(OCR)を使ってみましょう。

tesseract-ocr/tesseract

tesseractのインストール

macOSの場合は、brewでインストールできます。 デフォルトでは英語のみしか認識できませんので、日本語にも対応するように tesseract-lang を合わせてインストールします。

$ brew install tesseract tesseract-lang

インストール後、バージョンを確認してみましょう。

$ tesseract -v
tesseract 5.2.0
 leptonica-1.82.0
  libgif 5.2.1 : libjpeg 9e : libpng 1.6.37 : libtiff 4.4.0 : zlib 1.2.11 ...

メモ: 上のバージョン出力は記事執筆時(2022年)のものです。brew upgrade 後は異なるバージョンが表示されます。

日本語が使えるか確認するには、--list-langs オプションが便利です。

$ tesseract --list-langs
List of available languages (3):
eng
jpn
jpn_vert

jpn が含まれていれば日本語OCRが使えます。

さっそく、文字が含まれているこちらの画像をOCRしてみましょう。

こころ - 青空文庫より

日本語の文字でしたら、次のようにして tesseract を実行します。

$ tesseract kokoro-captured.png out -l jpn

out.txt が出力され、画像内の文字をテキストとして抽出できました。

画像内の文字をテキストとして抽出

テキストが埋め込まれたPDFにする

テキストが埋め込まれたPDFにするには、次のように実行します。

$ tesseract kokoro-captured.png out -l eng+jpn pdf

これで、画像の上に透明なテキストが追加されているはずです。PDF内の文字が検索できるようになりましたね!

検索できている

自炊したPDFをテキスト埋め込みPDFにする

ここからは、自炊したPDFをテキスト埋め込みPDFにしていく方法を解説します。

popplerのインストール

PDFをPNGファイルに変換する pdftoppm と、複数のPDFファイルを一つにまとめる pdfunite が必要になります。これらを使えるようにするため brewpoppler をインストールしましょう。

$ brew install poppler

PDFから各ページをPNG画像へ変換する(pdftoppm)

pdftoppmコマンドを用いて、PDFをPNG形式の画像に変換します。

$ mkdir tmp
$ pdftoppm -png -r 200 -gray 自炊ファイル.pdf tmp/page

ここではグレースケールにしてますが、カラーで表示したい場合は-grayを削除してください。

pdftoppm の主なオプションです。

オプション意味
-scale-to画像サイズを指定したピクセル数に縮小する
-r 数値DPIの値(デフォルトは150)
-grayグレースケールで出力する(PGM形式)
-pngPNG形式で出力する
-jpegJPEG形式で出力する

-r オプション、つまりDPIの値は元のPDFファイルによって調節する必要があります。高くしすぎると処理に時間がかかり、ファイルサイズも大きくなってしまいますのでご注意ください。

tesseractでOCR処理

PDFファイルを一枚一枚の画像に出力したところで、それらに tesseract でOCR処理を施してPDF化していきます。つぎのようにパイプで連携させて処理させます。

$ find "./tmp" -type f -name "*.png" | sed 's/\.png$//' | xargs -P8 -n1 -I% tesseract %.png % -l eng+jpn pdf

xargs-P オプションは、同時実行数の最大値、-n オプションは、xargs に渡す引数の最大値、-I オプションは、標準入力より渡されたデータを、 任意の引数に展開することが可能です。

これでテキストが埋め込まれたPDFファイルが作成できました。ただし、ページ毎にファイルがバラバラですので、pdfunite を使って一つのPDFにします。

pdfuniteで複数のPDFファイルを連結して、ひとつのPDFにまとめる

次のようにして、複数のPDFファイルをひとつのPDFにまとめます。

$ pdfunite $(ls -v tmp/*.pdf) output.pdf

ls -v で自然順(1, 2, 10 の順)に並べてから結合するため、ページ順が崩れません。

さて、tmp ディレクトリ内の画像やPDFは必要ありませんので削除してしまいましょう。

$ mv tmp ~/.Trash

これでめでたく、自炊したPDFファイルにテキスト文字を埋め込むことができました。完成したpdfは、2倍くらいのサイズになりました。

 $ du -sh *
 15M	自炊ファイル.pdf
 29M	output.pdf

一括で実行できるシェルスクリプト

ここまでの流れを一括で処理できるシェルスクリプトを作ってみました。

#!/bin/bash

PDF_PATH="$1"
FILE_NAME="$(basename "$PDF_PATH" .pdf)"
TMP_DIR="tmp_${FILE_NAME}"
TRASH_DIR=~/.Trash

mkdir "$TMP_DIR"

pdftoppm -png -gray -scale-to 1000 "$PDF_PATH" "$TMP_DIR/page"
find "./$TMP_DIR" -type f -name "*.png" | sed 's/\.png$//' | xargs -P8 -n1 -I% tesseract %.png % -l eng+jpn pdf

mv "$FILE_NAME.pdf" "~$FILE_NAME.pdf"

pdfunite $(ls -v "$TMP_DIR"/*.pdf) "$FILE_NAME.pdf"

mv "$TMP_DIR" "$TRASH_DIR"

このようにして実行します。

./ocr.sh 自炊ファイル.pdf

元データは ~自炊ファイル.pdf としてバックアップされます。

【おまけ】自炊スキャンでつかえる神アプリ「vFlat」が超便利!

さいごに、できるだけお金をかけずに自炊ができるスキャナーアプリをご紹介します。App StoreやGoogle Playで「vFlat」で探してみてください。 このアプリ、無料ですが本当にすごいです!次のようなことができちゃいます。

  • 本の歪みを直してくれる
  • 指が映っても削除してくれる
  • 自動でシャッターを押してくれる
  • 日本語もOCR処理でテキストを埋め込める

vFlatアプリ vFlatでスキャン

もちろん裁断してスキャンする方法に比べれば歪みは残りますが、比較的キレイに自炊してくれます。他のスキャナアプリで満足できなかった方は、vFlatをぜひお試しください。 ただし、一日つかえるOCRのページ数が限られてます。そのため、OCR処理はこの記事でご紹介した tesseract を使うと良いです。

▼ こんな感じで、サクッと自炊できちゃいます。

vFlatとtesseractで自炊

本格的な自炊に役立つアイテム

関連記事