スキャンしたデータは大体PDFファイルになっているし、総務省の資料などをダウンロードするとPDFファイルである事が多い事から、PDFファイルをWEBサービスでどこまで扱えるかを検討している。
最近のブラウザはスマホでもPCでもPDFファイルは閲覧できるようになっているが、容量が大きいファイルを閲覧の度にダウンロードするのは、億劫。
書籍などをスキャンしたデータをサーバーに置いておいて、必用なページだけみることができれば、いちいちPDFファイルをダウンロードして閲覧するよりも便利なのではないか?
ということで、こうした視点で行うWEBサービス構築の裏システムになるPDFファイルの扱いをサーバーサイドで行うコマンドについて調べてみました。
調査結果
PDFファイルを画像として分割出力できるソフトウェアは沢山あります。
本家のAcrobatはWindowsとMacのアプリケーションなので、これは除外。
確かにWindowsでは、PDFファイルを変換したり画像を抜き出したりするフリーソフトが山のようにあります。
Macも負けず劣らず、フリーソフトも有料ソフトも沢山ありますが、今回やりたいのはサーバーサイドでのコマンドラインによる、PDF画像変換。
Imagemagick
画像操作に卓越していて有名なのが「Imagemagick」です。
歴史も古く、対応しているフォーマットも半端なく多いです。
よほど特殊な画像フォーマットでない限り、変換や画像操作はほぼほぼできてしまいます。
ただし、CPU不可が高いという点と、動作速度が遅い。この2点でどうしてもWEBサービスでのリアルタイムに使うことは難しく、バッチ処理で行うツールになってしまいます。
pdftoppm
WEBを検索しているとちょいちょい「pdftoppm」というコマンドが紹介されている。
どうやらこれが良さそうなので、使ってみたいと思う。
参考サイト:
Xpdf | TEX Wiki
インストール方法
# Ubuntuへのインストール
$ sudo apt-get install xpdf
# Centos
※ダウンロードサイトからソースを落としてインストールしましょう。
# MacOSX
$ brew install xpdf
$ brew install Caskroom/cask/xquartz
$ brew install homebrew/x11/xpdf
ちなみに、ダウンロードサイトはこちら
XpdfReader
自分でコンパイルしてインストールするのも良し。
これによりインストールされるコマンドは以下の通りです。
1. pdfdetach :PDFファイルにアタッチされた部分をファイルで抽出
2. pdffonts :ファイルのフォント情報を表示
3. pdfimages :PDFデータから画像を抽出
4. pdfinfo :プロパティ情報などを表示
5. pdftohtml :PDFをHTML形式に変換
6. pdftopng :PDFの各ページをPNG画像に変換
7. pdftoppm :PDFをPPM画像形式に変換
8. pdftops :PDFをPostScriptファイルに変換
9. pdftotext :PDFファイルからテキストを抽出
実行方法
直接PNGに変換できるコマンドもありますが、できるだけ容量削減をしたいので、JPEG変換に拘ってみます。ということで「pdftoppm」コマンドを使います。
PDFファイルをページ別にJPEGファイルに変換するのは以下のコマンド
$ pdftoppm -jpeg '%ファイル名' '%output/pdf'
%output/pdf-001.jpg
%output/pdf-002.jpg
%output/pdf-003.jpg
...
これでページ数分のJPEGファイルが連番で作成されます。
アウトプット先の/pdfは、プレフィックスになります。(これを書かないと「-001.jpg」というファイル名になります。)
関連機能のコマンドサンプル
# 単一ページのみを抜き出す(サンプルは10ページ目を抜き出す)
$ pdftoppm -jpeg -f 10 -l 10 file.pdf > output/pdf-10.jpg
# ページ情報の取得
$ pdfinfo file.pdf
# PDFファイルの総ページ数の取得
$ pdfinfo file.pdf | awk 'BEGIN{FS=": *"}{if($1~/Pages/){print $2}}'
※awkで:をsplitして、いらないスペースをトリムしている。
とりあえずこの程度の操作ができれば、要件は満たされます。
気をつける点と出来ないこと
コマンド操作をしていて幾つか気がついた点を書いておきます。
・PDFファイル名に[]が使われている場合は、"(ダブルクォート)だとエラーが出る。
→エスケープしてもダメ
→解決:'シングルクォートにするとできた
・単一ページ抜き出しは1ページは「0」ではなく「1」を指定
→プログラム連携する場合は1スタートで行いましょう。
他モジュールとの違い
Imagemagickは、出力した画像を非常に細かく変形したり、色調整を行ったり、トリミングしたりできますが、xpdfはそのへんはあまり得意ではないようです。
元素材としての抜き出しや情報取得はxpdfで行い、画像操作はImagemagickで行うというのがいい使い方だと思います。
ちなみに、imagemagickとの速度調査をしてみました。
# 227ページ(29MB)の書籍スキャンしたPDFデータをjpegに変換した時の処理速度
- Imagemagick
$ time convert -geometry 100% -density 100% test.pdf test_imagemagick/pdf.jpg
real 0m31.857s
user 0m27.520s
sys 0m1.410s
- pdftoppm
$ time pdftoppm -jpeg test.pdf test_xpdf/pdf
real 0m14.860s
user 0m11.880s
sys 0m0.520s
2倍以上のスピードで変換できてしまいます。
まとめ
ビジネス業界ではまだまだ現役のPDFファイルですが、何故使われているかを考えてみると、ファイル単体でテキストデータを保持しているがOSにインストールされていないフォント情報などもファイルに保持しており、印刷などをする際のトラブルが極力少ないからなんですね。
パワポやワードなどのデータは、別の会社に送った際に、対応フォントがインストールされていないPCでは、文字が潰れたり勝手に改行されたり、思いもよらない見栄えになってしまうため、PDFファイルは重宝されるのでしょうね。
また、スキャンされたデータの保存形式がPDFになっている端末も非常に多く、最近の機種であれば、自動的に文字認識(OCR)をして、PDFファイルにテキストデータも付けて、ビューワで検索できるようにもなっているようです。(※スキャナの機種により精度は異なります)
個人的には、読みたい本を全てスキャンしてサーバーに置いておいて、自宅にいないときでも、旅行に行っている時や、出先で自宅にある本の情報が欲しくなった時などに、簡単に見れるようにできるといいという思いで、それができるWEBサービスを構築しています。
スマホアプリに入れればいいという意見もありますが、冊数が極端に増えてくるとスマホの端末ストレージでは耐えきれず、テラバイトぐらいの容量が欲しくなったため、WEBサービスである必用が生まれました。
今後はもっとこういうニーズが増えてくるでしょうね。