PDFからテキスト情報を引っ張り出す

やっと出来た。
調査だけで1週間半近くもかかりました。全くもって最悪です。
ここにテキスト情報があるというのを特定するのに2日、その値を文字に戻すのに1週間…
今回はiTextというライブラリを利用して、調査をしていたのだが、開く側の情報は全然なく、
出力側のexampleしか無いiTextの中身をしげしげと眺めつつ、機能があるのか無いのかとかを
見た結果、余計な時間がかかってしまった。
まあ、自力で解凍のロジックを作る事を考えればマシなのかもしれんけど。

結論から行くと、iTextには文字を元に戻す機能は無さそうです。
あるのかもしれないけど見つからなかった。
大した作業でも無かったので、この部分は自力実装としました。
時間があったら全部を自力で組み直すか…

結果、サンプルソースにならない状況になってしまったので、大まかな手順のみ説明。
1.xrefエントリーからオブジェクトの一覧を取得
2.trailerからrootオブジェクトを取得
3.rootオブジェクトからPageTreeを取得
4.PageTreeから各Pageオブジェクトを取得
5.Pageオブジェクトから、ContentsとResourcesを取得
6.Resourceの中からFontを取得
7.Fontの中からCMapの情報を取得
8.Contentsの中から描画関連の情報を取得
9.8の中から必要な情報を引っ張りだす
となります。
リファレンスを読む際の参考にでもしてください。

ターゲットを文字列だけとした場合、ポイントになるのは、8の中でもTf, Tj, TJで終わる行
Tfの行がフォントを選択している部分で、この行を見ながら6,7で取得したフォント情報とマッチさせる。
Tj, TJの行がテキストが入っている行で、この中から(xxxx)もしくはの部分を取得
(xxxx)は、そのままxxxxで出力する。
は、16進表記で文字が指定されているので、16進の文字コードから文字を作成する必要がある。
この工程で気をつけなければならないのは、7番の工程で取得したCMapの存在。
このCMapには、文字の変換リストが用意されていて、この変換リストを使って変換をしないと、もともとの文字にはならない。

最近のPDFは基本圧縮されているので、本当は7とか8の工程で、PDFにStreamとして埋め込まれている情報を解凍してあげて、
そのうえで解析をする必要があります。