PDFからテキストや画像を抽出 PDFBox
ApacheのPDFライブラリにPDFBoxがあります。これはオープンソースのJavaのPDFライブラリです。
以前JavaScriptのPDFライブラリのPDF-LIBを使ってPDFを作成しました。今度は読み込みをしたいと思ったのですがPDF-LIBではできなさそうだったので、PDFBoxを使うことにしました。言語はJavaとなってしまいますが、ファイル内に存在するテキストや画像を抽出することができます。またテキスト処理時はOCR機能も働くようです。
Java環境の構築
PDFBoxはJavaの環境で稼働しますのでランタイムが必要です。今回利用するバージョン2.0.27はJavaのバージョン6以上、PDFBoxの次期のバージョンである3系ではJavaのバージョン8以上となっています。
Javaの環境がない場合はAdoptOpenJDKなどからダウンロードできます。
先に紹介した、AdoptOpenJDKのページでは利用するOSやアーキテクチャ別にインストーラーが用意されています。自身の環境に合わせて選択してください。
Javaのバージョンは先の要件通りなのでリストにあるものならどれでもいいのですが、迷ったらLTS(長期サポート)の最新版である17がいいのではないでしょうか。
バージョンが新しいことが起因するエラーがでるようならひとつ前の11にします。
筆者は8(一番古いサポート中のLTS版)の環境がインストール済みでしたので、それを利用しました。
今回やろうとしている事はJREがあれば動きますが、JDK(Java開発環境を含むバージョン)をインストールしても問題ありません。
Javaの環境があるかどうかは、PowerShellやコマンドプロンプトから確認できます、他のアプリで利用してる場合はバージョンの変更が影響する場合もあるので、無いと思っても確認していた方が無難です。
PS > java --version
openjdk 17.0.4.1 2022-08-12
OpenJDK Runtime Environment Temurin-17.0.4.1+1 (build 17.0.4.1+1)
OpenJDK 64-Bit Server VM Temurin-17.0.4.1+1 (build 17.0.4.1+1, mixed mode, sharing)
上記のような表示がでた場合はバージョン17がインストールされています。また他のバージョンのインストールもあるかもしれません。
コマンドが見つからない旨のエラーが出た場合、パスが通っていない場所にJava環境がある可能性もありますが、その場合は新にインストールしても影響は少ないと思います。
PDFBoxのダウンロード
PDFBoxはバージョンや役割によりいくつかのjarファイルに分割されて配布されています。今回利用するのはバージョン2系のスタンドアローン版「pdfbox-app-2.0.27.jar」を用います。
ダウンロードページからダウンロードしてきます。
PDFからテキストファイルを抽出
ダウンロードしてきたpdfbox-app-2.0.27.jarを好きな場所に移動させます。ここではd:¥pdfフォルダを作成しました。
同じ階層にテキストを抽出したいpdfファイルも配置します。ここではsample.pdfとしています。
この状態で次のようにコマンドを入力すると、sample.pdfからテキストデータが抽出され、sample.txtファイルに出力されます。
PS > cd d:¥pdf
PS > java -jar .\pdfbox-app-2.0.27.jar ExtractText sample.pdf
サンプルとしてデジタル庁の「デジタル社会の実現に向けた重点計画(概要)」のPDFファイルからテキストを抽出してみたいと思います。
エラーもでたりしましたが、抽出できました。
ExtractTextの後に渡すことのできるオプションは次の通りです。
java -jar pdfbox-app.jar ExtraxtText [オプション] 入力ファイル [出力ファイル]
- -alwaysNext
IO例外が発生しても次のページを処理します。
- -password
PDFのパスワードを指定します。
- -encoding
テキストファイルのエンコーディングを指定します。MS932、SJIS、UTF-8、UTF-16BEなどが指定できます。
- -console
ファイルの代わりにコンソールに出力します。
- -html
HTMLとして出力します。ファイルを指定しない場合の拡張子は.htmlになります。
- -sort
出力前にソートを行います
- -ignoreBeads
ビーズによる切り離しを無効にします。たとえばaaa・bbbという文字をaaa bbbとして判断することを無効にするものだと思うのですが実稼働による確認が取れませんでした。
詳細は公式ページのこのあたりが参考になると思います。
- -debug
ロード時間などのデバッグ情報を出力します
- -rotationMagic
ページ毎に回転やゆがみを0度に戻して抽出します。html出力時は無視されます。
PDFから文字列を抽出するだけなのになぜこのオプションがあるのだろうと思って試してみたらOCR機能(画像から文字の抽出)も行っているようでした。そのためのオプションだと思われます。
だた試してみたところ、日本語だと?誤字も多いようです。
- -startPage
抽出開始ページを指定します
- -endPage
抽出終了ページを指定します
画像の抽出
今度は画像を抽出したいと思います。先ほどのデジタル庁のPDFを使います。
PS > java -jar .\pdfbox-app-2.0.27.jar ExtractImages sample.pdf
Writing image: sample-1
Writing image: sample-2
Writing image: sample-3
Writing image: sample-4
Writing image: sample-5
抽出されたイメージが同じフォルダにsample-シーケンス番号.jpgという形で出力されます。
ExtractTextよりも少ないですが、ExtractImagesにもオプションが存在します。
java -jar pdfbox-app.jar ExtraxtImages [オプション] 入力ファイル;
- -password
PDFのパスワードを指定します。
- -prefix
画像ファイルにつけるプレフィックス、先の例では「sample」の部分を指定します。
- -directJPEG
カラーパレットを無視してJPEG画像を強制的に抽出します。
1ページまるごと画像に
旧バージョン
PDFの1ページをまるごとひとつの画像にしたい場合は、PDFToImageコマンドを使います。この時、x,y座標を指定して指定した範囲だけを画像化することもできます。
java -jar pdfbox-app.jar PDFToImage [オプション] 入力ファイル
こちらのオプションは次の通りです。上記のコマンドで既出オプションの説明は省略します。
- -password
- -imageType
保存形式を指定するオプションです。デフォルトはjpgで、現在のところ他に有効な値はpngだけのようです。
- -outputPrefix
ExtractImagesと同様のオプションです。デフォルトはファイル名です。
- -startPage
- -endPage
- -dpi
画像出力時のdpiを指定します。デフォルトはディスプレイの設定より取得した値のようです。
- -color
bilevel、gray、rgb、rgbaより選択できます。デフォルトはrgbです。
- -cropbox
int型の引数を4つとり画像化する領域を指定できます。それぞれの引数は、開始x位置、開始y位置、終了x位置、終了y位置です。y軸は下辺が0で上に伸びます。
- -time
標準出力にレンダリングにかかった時間を出力します。
バージョンの堺は調べていませんが、3.0.3では、PDFToImage ではなく render を指定するようです。また入力ファイルも --input= オプションとしてい指定するように変更されました。出力画像のデフォルトも jpg に変わっています。
java -jar pdfbox-app.jar render --input=入力ファイル
印刷
抽出とは若干ニュアンスが違うかもしれませんが、印刷も可能です。
java -jar pdfbox-app.jar PrintPDF [オプション] 入力ファイル
- -password
- -silentPrint
- -printerName
プリンタ名を指定します。
- -orientation
印刷方向を指定します。auto、portrait(縦)、landscape(横)の値が指定でき、デフォルトはautoです。
- -border
境界を印刷します。
- -dpi