Origamiを使ってPDF中の画像を調整する

ScanSnapで検索可能なPDFにしたとする。このとき、せっかくだから検索可能なまま画像の調整をしたくなる。だが、その種のことができるツールというのをどうもうまく探せない。いかにも何かありそうなものなのだけど。

それなら作ればよい。PDFを扱うライブラリはたくさんある。最終的にできるかどうかはともかくとして、ちょっと試すくらいならやりようがあるだろう。

そう思ってあれこれやっていたのが2010年12月くらいのこと。その当時の環境ではこれが意外にめんどうで途中までやりかけたものの放ってしまっていた。その時使っていたライブラリのバージョンが上がってリリース版が出たというのを先日知って、もう一度やってみることにした。すると意外にもこれが結構簡単にできてしまった。

当時でもPDFを扱うライブラリは簡単にいくつも見付かった。代表的なのはPDF::WriterやPrawn。その他のいくつかのライブラリとともに試してみた。しかし、それらにはPDFファイルを新たに作成する機能はいろいろとあるものの、既存のPDFファイルを改変する機能がほとんどなかった。

しかたないのでPDFファイルを直接編集するものを作り始めたのだが、すぐにPDFの自由さ知ることになる。というのはScanSnapが出力するPDF、Acrobatで編集したPDF、Preview.appで編集したPDFと、みな構造が異なっていたのである。これではまともにPDFを解析しなければ対応しきれない。

そうして改めて探し直して見付けたのが、開発中だったOrigamiである。

現在までにバージョン1.0がリリースされ、gemでのインストールも可能となっている。現時点でのバージョンは1.2.3。2010年末の時点ではドキュメントもサンプルもほとんどなかったが、このバージョンにはいくつかの有用なツールが含まれている。手軽にPDFをいじりたいというときにはすぐに手本にできるものが揃っているといえるだろう。

  • pdf2graph - Generates a Graphviz DOT or GraphML file out of a PDF document
  • pdf2pdfa - Enforces a document to be rendered as PDF/A
  • pdfcop - PDF document filtering engine using Origami
  • pdfdecompress - Uncompresses all binary streams of a PDF document
  • pdfencrypt/pdfdecrypt - Encrypts/Decrypts a PDF document (Supports RC4 40 to 128 bits, AES128, AES256)
  • pdfextract - Extracts various data out of a document (streams, scripts, images, fonts, metadata, attachments)
  • pdfmetadata - Prints out the metadata contained in a PDF document
  • pdfsh - OrigamiによるPDF操作にカスタマイズしたirb
  • pdfwalker - PDFの構造を表示するGUIツール(Ruby/Gtk2)

このうちのpdfextractを参考にして、PDFに含まれる画像をImageMagickで編集するスクリプトを作ってみた。PDFの仕様は公開されているものを拾い読みした程度なので適切ではない部分があるかもしれないが、evinceやPreview.app、i文庫で参照できることを確認した。

gist

動作確認には、紙が薄いことがよく知られている角川スニーカー文庫をスキャンしたものを使ったた。同文庫は紙のまま読んでいてもよく透ける。スキャン結果もそれに応じたものとなる。下は生成されたPDFと処理したPDFをi文庫で参照したときのスクリーンショットである。

処理前 処理後

このように文章ページではスッキリしたものとなった。ところが、ちょうどこの裏のページにある挿絵では以下の切り抜きのようにやりすぎてしまっている。なかなか難しい。(なお、動作確認に使ったのは以前紹介(?)したことのある「子ひつじは迷わない 泳ぐひつじが3びき」の15〜17ページ。)

処理前 処理後

手元では挿絵ページやカラーページはエクセレントで、それ以外はスーパーファインでスキャンして、Preview.appでマージしている。よってdpiをキーに調整内容を変えればもう少しよい結果を得られるだろう。また、ページの内容に応じて処理を変えるようにしたり、ページを指定しての画像差し替えを可能にすればツールとして実用的になるかもしれない。ただ、そのためにはページ構造を扱えるよう作り込まなければならない。

ともあれ、2010年当時には、こういう単純なコードだとメモリをどんどん食いつぶしていってくれたのだが、リリース版で改善されたのか、Ruby 1.9.3を使っているからなのか、200ページちょっとの文庫本を特に問題なく処理できた。なかなかよい。