事象

PDF ファイルを OCR にかけた後、テキスト情報が追加されただけなのにファイルサイズが約 10 倍に肥大化することがある。

特に yomitoku を使用した場合に発生する。

原因

pdfimages -list による解析の結果、OCR ツールが画像のエンコーディング形式を非効率なものへ変換していたことが原因であることがわかった。

OCR 前:

page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image    2336  1654  gray    1   1  ccitt  no      5448  0   200   200 15.2K 3.2%
   2     1 image    2336  1654  gray    1   1  ccitt  no         3  0   200   200 9324B 1.9%
   3     2 image    2336  1654  gray    1   1  ccitt  no         6  0   200   200 47.9K  10%
   4     3 image    2336  1654  gray    1   1  ccitt  no         9  0   200   200 17.7K 3.8%
   5     4 image    2336  1654  gray    1   1  ccitt  no        12  0   200   200 51.0K  11%
   6     5 image    2336  1654  gray    1   1  ccitt  no        15  0   200   200 13.3K 2.8%
   7     6 image    2336  1654  gray    1   1  ccitt  no        18  0   200   200 72.8K  15%
   8     7 image    2336  1654  gray    1   1  ccitt  no        21  0   200   200 52.6K  11%
(snip)

OCR 後:

page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image    1655  2337  rgb     3   8  jpeg   no         3  0    72    72  178K 1.6%
   2     1 image    1655  2337  rgb     3   8  jpeg   no         5  0    72    72  146K 1.3%
   3     2 image    1655  2337  rgb     3   8  jpeg   no         7  0    72    72  253K 2.2%
   4     3 image    1655  2337  rgb     3   8  jpeg   no         9  0    72    72  240K 2.1%
   5     4 image    1655  2337  rgb     3   8  jpeg   no        11  0    72    72  550K 4.9%
   6     5 image    1655  2337  rgb     3   8  jpeg   no        13  0    72    72  193K 1.7%
   7     6 image    1655  2337  rgb     3   8  jpeg   no        15  0    72    72  576K 5.1%
   8     7 image    1655  2337  rgb     3   8  jpeg   no        17  0    72    72  605K 5.3%
(snip)

CCITT は 二値画像に特化したフォーマットだが、これが 24 bit カラーの jpeg になってしまっている。

pdfimages は poppler-tools のコマンドである。

解決策: テキストレイヤーの移植

OCR 後のファイルからテキストレイヤーを取り出し、OCR 前のファイルにオーバーレイとして追加する。

Step1

OCR 後のファイルからテキストレイヤーを抽出する。

gs -o text_only.pdf -sDEVICE=pdfwrite -dFILTERIMAGE ocr_bloated.pdf

ここで生成される PDF はテキスト情報と位置だけを持っていてフォント等が設定されていないのでビューアで開いても真っ白になる。ただしテキスト選択だけはできる。

Step2

画像とテキストを合成する。

qpdf original.pdf --linearize --overlay text_only.pdf -- output.pdf

--linearize は Web 高速表示に対応するためのオプションで、なくても良い。

うまくいかなかった手法

最初のアプローチとして mutool, qpdf, magick, gs, ocrmypdf 等を使って、OCR 後のファイルの画像を最適化しようとした。しかし、画像フォーマットを CCITT に戻すことができず、ファイルサイズはほとんど減少しなかった。


"上"のページ: 自炊