やりたいこと
PDF ファイル内の画像を文字認識して、画像上に透明なフォントのテキストを埋め込んだ PDF ファイルを生成する。
pymupdf から tesseract を使用することで、PDF ファイル内の画像の文字認識を行うことができる。
tesseract
tesseract のインストール
$ sudo yum install epel-release
$ sudo yum install tesseract
$ sudo yum install tesseract-devel
$ sudo yum install tesseract-langpack-jpn
tesseract の動作確認
tesseract コマンドで画像ファイルを OCR してテキストを出力することができる。
$ tesseract -l jpn {image_file} {text_prefix}
実行例
$ tesseract -l jpn test.png ocr
$ cat result.txt
これはテストです。
これもテストです。
それもテストです。
pymupdf + tesseract
pymupdf から tesseract を使って pdf 内の画像を OCR して、OCR 結果のテキストを画像に重ねて透明なテキストを pdf に埋め込むことができる。
pymupdf のインストール
$ pip install pymupdf
日本語フォントのインストール
$ sudo yum install google-noto-sans-cjk-jp-fonts
pymupdf + tesseract のプログラム例
ocr.py
import os
import sys
import pymupdf
def add_ocr_result(org_file_name, ocr_file_name, font_name, font_path):
doc = pymupdf.open(org_file_name)
for page in doc:
page.insert_font(fontname=font_name, fontfile=font_path)
# flags=3: 一般的に "3" を使用
# full=True: ページ全体を画像化して OCR
# full=False: 画像のみを OCR
text_page = page.get_textpage_ocr(flags=3, language="jpn", full=False)
text_dict = page.get_text("dict", textpage=text_page)
for block in text_dict["blocks"]:
if "lines" in block:
for line in block["lines"]:
for span in line["spans"]:
print(span["text"])
# render_mode=3: 不可視テキストモード
page.insert_text(
span["origin"],
span["text"],
fontsize=span["size"],
fontname=font_name,
render_mode=3
)
doc.save(ocr_file_name)
doc.close()
def main():
org_file_name = sys.argv[1]
ocr_file_name = sys.argv[2]
font_name = "ocr-jpn-font"
font_path = "/usr/share/fonts/google-noto-cjk/NotoSansCJKjp-Regular.otf"
# print(f"org_file_name: {org_file_name}")
# print(f"ocr_file_name: {ocr_file_name}")
add_ocr_result(org_file_name, ocr_file_name, font_name, font_path)
return 0
if __name__ == '__main__':
res = main()
exit(res)
実行
上記のプログラムを実行すると、OCR の結果のテキストが画像上に透明なフォント
$ python ocr.py test.pdf ocr.pdf
これ
はテス
ト
で
す
。
これ
も
テス
ト
で
す
。
それ
も
テス
ト
で
す
。
OCR 前の pdf ファイルでは画像のため、文字列をドラッグできないが、OCR 後の pdf ファイルでは透明なテキストが埋め込まれているため、ドラッグしてコピー・ペーストすることができる。
参考
pdf を png に変換
$ convert -density 150 -background white -flatten {pdf} {png}
png を pdf に変換
$ convert -page A4 {png} {pdf}

