アルファのブログ

ことば、計算機、SF、ヒコーキ

alpha3166 alpha3166

自炊PDFを第3世代iPadに最適化する その2

2012-04-01作成

(→その1、その2、その3その4)

前回は、自炊したPDFをどのぐらいの画素数・圧縮率にすると第3世代iPadに最適かを探りました。私の結論としては、本の判型がA5判(148×210mm)までなら見開き表示前提で1024×1536pxにリサイズ、それより大きい判型なら1ページ表示の前提で1536×2048pxにリサイズ、またJPEGの圧縮率は50あたりが最適、というものでした。

今回は、ChainLPを使って実際に最適化PDFを作ったときのメモです。

判型を調べる

まず、本の判型(というか、実際には縦横の画素数)を知る必要があるわけですが、800個以上あるPDFの画面サイズを個別に調べるのは大変なので、FreeBSD上でxpdfとImageMagickを使って一気に調べる方法を考えてみました。準備として、portsからxpdf(graphics/xpdf)とImageMagick(graphics/ImageMagick)をインストールしておきます。

考え方としては、xpdfに含まれるpdfimagesコマンドを使って30ページ目だけをJPEGとして抽出し、ImageMagickに含まれるidentifyコマンドでそのJPEGの縦横の画素数を表示させます。30ページ目というのは適当で、そのへんなら表紙やジャケットじゃなくて典型的な本文ページだろうという程度の意味合いです。あとはシェルのfor文で、それを全PDFに対して繰り返していきます。

for file in *.pdf; do
    echo -n "$file "
    pdfimages -f 30 -l 30 -j "$file" tmp
    identify -format "%w %h" tmp*.jpg
done > pdfsize.txt

上記の実行例はBシェル系です。pdfimagesの-fは抽出する最初のページ、-lは最後のページ、-jはJPEGとして抽出の意味です。第2引数のtmpは抽出するJPEGのファイル名です。tmpと指定すると、tmp-000.jpgといったファイルができあがります。identifyの-formatで指定している%wは横の画素数、%hは縦の画素数を表示させるという意味です。

ここでできた一覧をExcelに取り込み、画素数を300で割って25.4を掛けるとミリメートルに換算できます(オリジナルは300dpi、1インチは25.4mmなので)。うちの本をサイズで分類すると、下記の13種類でした。マイナスはやや小さい、プラスはやや大きいサイズを表します。

額縁問題

さて、上記のように判型を調べて、A5判以下に分類したものは1024×1536pxに、A5判+以上に分類したものは1536×2048pxに変換することにしたのですが、ここで単純にChainLPの「通常」設定で画素数を変換すると、iPadでの額縁問題が出てきます。

たとえば、少し縦長気味の本をChainLPのデフォルト設定でiPadの画素数目一杯の1563×2048pxに変換すると、ページの左右に白い余白が付け足されますが、これをi文庫HDなどで見開き表示にすると、さらにページの上下にも余白ができてしまい、額縁に入ったような状態になってしまいます。逆に、やや縦横比が小さくてずんぐりむっくりの本を見開き表示用の1024×1536pxに変換すると、ChainLPがページの上下に白い余白を付け足しますが、今度は1ページ表示にしたときに左右に余白があらわれて、こちらも額縁表示となります。

img

これは、1ページ表示と見開き表示で縦横の比率が変わるために起こる問題で、ChainLPが余白を付けないようにしてくれればいいのですが、残念ながら現状はそのモードがありません。似たような「横固定」「縦固定」モードを使うと余白はつかなくなるのですが、これらは文字通り横か縦の画素数を固定してもう一辺を可変にするものなので、例えばずんぐりむっくり本を縦2048px固定にすると、横が1536を超えてしまって、適切な画素数になりません。

そこで、さきほど作ったExcelシートで縦横比を計算して(これは単純に縦の画素数を横の画素数で割れば求められます)……

という設定で画素数変換をすることにしました。

綴じ方向

PDFを作ったあとに右綴じ/左綴じの設定を変更するのも面倒なので、さっきのExcelに綴じ方向を書いておいて、ChainLPでの変換時に指定することにしました。

変換の自動化

これでChainLPの設定パラメータが出揃いました。

可変パラメータとしては、

  1. 画素数を1536×2048pxにするか、1024×1536pxにするか
  2. 横固定にするか、縦固定にするか
  3. 右綴じにするか、左綴じにするか

の3つがあるので、変換の種類は2×2×2の8通りあることになります。

これをChainLPの画面でいちいち設定するのは大変なので、テキストファイルにコマンドラインを書いて、バッチ処理できるようにします。

コマンドラインの基本は、ChainLPのヘルプにもあるとおり、

ChainLP -b -i 入力PDF -o 出力PDF -ini 設定ファイル -r2l

という感じになります。-bはバッチ処理、-r2lは右綴じを表します。左綴じの場合は-l2rになります。-iniで指定している設定ファイルは、ChainLPを終了したときにできるdefault.iniのパスを指定するものですが、いろいろ設定を変えてChainLPを終了→default.iniを別ファイルにコピー→またChainLPを立ち上げて設定変更→default.iniを別ファイルにコピー、という手順を繰り返しておけば、任意のiniファイルを-iniオプションに指定することで、ファイルごとに変換パラメータを変えることができます。

上記1.の画素数は、コマンドラインの-wと-hオプションで指定できるとヘルプに書いてあるのですが、今回試した限りでは、-wと-hを付けると誤ったオプション扱いでエラーとなってしまいました。そこで、画素数もiniファイルで指定することにします。2.の横固定/縦固定は、もともとコマンドラインオプションには無いので、これもiniファイルで指定します。3.の閉じ方向は、コマンドラインオプションの-r2lと-l2rで上書きできるので、こちらを使うことにします。というわけで、

という4種類のiniファイルを作って、これをファイルに応じて切り替えることになりました。JPEGのクオリティはいずれも50にし、「全て挿絵にチェックする」を有効にしてあります。

コマンドラインは、ExcelのIF関数を使って、判型・縦横比・綴じ方向に応じたものを文字列操作で作成します。それをテキストファイルに貼付け、○○.batの拡張子でどこかに保存します。あとはそのbatファイルをダブルクリックすると、全自動で変換が始まるので、でき上がりを寝て待ちます。

こんな感じで、Retinaディスプレイの能力を活かした文字クッキリの読書ができるようになりました。

全部FreeBSDでできる?

ところで、最初に本の判型を調べるのに使ったxpdfのpdfimagesを使えば、PDFに含まれる全JPEG画像を簡単に抽出できますし、ImageMagickのconvertを使えば、各JPEG画像を一定の画素数に収まるよう縮小しながらPDFにまとめることも簡単にできてしまいます。さすがに綴じ方向までは指定できないようですが、convertなら額縁問題も回避できます。例えばこんな感じ。

pdfimages -j 入力.pdf tmp
convert -quality 50 -resize 1024x1536\> tmp*.jpg 出力.pdf

が、実際にこれを試したところ、convertの途中でOSもろとも死んでしまい、大変なことになってしまいました。ページ数が少なければ大丈夫なのですが、200ページぐらいの新書程度であっても途中で動かなくなってしまったので、ちょっと実用にはならなさそうです。残念。

(→その1、その2、その3その4)

※バージョンメモ