イントロダクション
ただただしさんのkindlizerは「自炊したPDFから余白を取り除いてKindle向けに最適化するRakefile」です。
RakefileとはRake処理のための手順ファイルです。
↑ Rakeとは伝統的なビルドツールMakeをRubyで作りなおしたものです。
↑ Makeは多くのソースコードから成るソフトウェアのコンパイル→リンク→インストールといった手続き(ビルド)を自動化するために昔から使われているツールです。Rakeではビルド手順の記述にRubyの文法が使えます。参考: http://www2s.biglobe.ne.jp/~idesaku/sss/tech/rake/
kindlizerではこのRakeを使って:
- PDFを1ページずつに分解
- →1ページずつ分析して余白を切り落とす
- →PDFにまとめ直す
- →メタ情報を付加する
という手順を自動化しているわけです。
この記事は、kindlizerがあまりに便利なのでひっくり返ったこと、にもかかわらずご本人以外が使っている感じがあまりしないことから、周辺情報を補って使いやすくするために書いています。対象は、自分でスキャンした書籍をKindleで読みたい方のうち、Mac OS XやLinuxのようなUnix環境にいくらかでも親しみのある方です。
作業環境はUnix的なOSなら何でも大丈夫だと思います。私はLionにアップデートしたばかりのMacbookでpdftkコンパイルに挫折して、FreeBSD 8.2Rで全部やるようにしました。
インストール
Rakefileはコピーして、目的のPDFと同じディレクトリに置くだけです。
他に必要なものは:
rakeコマンド
rakeはrubygemのパッケージです。freebsdでは
# cd /usr/ports/devel/rubygem-rake # make install clean
で入ります。rubygemの入っている環境では
# gem install rake --remote
で入るようです。
poppler-utils poppler-data imagemagick pdftk sam2p の各パッケージ
私はRakefileの説明をちゃんと読んでおらず、「ああpdfinfoとかが必要なのね」とxpdfを入れてしまいました。
popplerはxpdfから分岐したツールセットなのでxpdfでもよかったようですが、popplerの方が楽なのかも。
各パッケージには、次のような役割があります。
-
- poppler-utils: ページの切り出しに使うpdftoppmやメタデータを取り出すpdf-infoといったコマンドが入っている。
- poppler-data: PDFフォントのcMap等が入っている。
- imagemagick: 余白を分析して切り落とすconvertコマンドが入っている。
- sam2p: pngを単ページのPDFに変換するコマンドである。
- pdftk: 単ページのPDFを1冊にまとめ直す機能とメタ情報を付加する機能を使う。
Linux環境なら楽に入ると思います。
手順
- 作業ディレクトリにRakefileをコピーする。目的のPDFファイルも置く。
- Rakefileを編集し、SRC = 'sample.pdf' の行の「sample.pdf」を目的のPDFファイルの名前にする。
- 画像サイズを選ぶ。1ページを1画面で表示する(ポートレート)なら「SIZE = '560x735'」とする。Kindleを横向きに持って1ページに2画面ずつ使って表示する(ランドスケープ)なら、「SIZE = '720'」にする。
- rakeコマンドを実行する。
rakeコマンドはRakefileの内容に従って、以下のように作業を進めます:
- 元PDFからpdftkがメタデータを取り出し、metadata.txtというファイル名でセーブする。
- 作業ディレクトリにpgm、png、pdfという名のディレクトリが作られる
- pdftoppmコマンドが、元PDFファイルのスキャンイメージを1ページずつ、グレイスケールのビットマップで切り出し、tmp-001.pgm, tmp-002.pgm, tmp-003.pgm…といったPGMファイルを生成してpgmディレクトリに入れる。
- convertコマンドがこのPGMファイルの余白を取り除きつつPNGファイルに変換し、pngディレクトリに入れる。余白を取り除く手順は、
- convertでPGMをPNGに変換するたびにsam2pが呼ばれてPNGを1ページずつのPDFに変換し、pdfディレクトリに入れる。
- convertとsam2pによる変換が最後のページまで終わったらpdftkがすべてをまとめて単一のPDFファイルを作る。ファイル名は、元が「ベース名.pdf」なら「ベース名.out.pdf」となる。この名前はRakefileで指定できる。
- 単一のPDFファイルができたら、もう一度pdftkが呼ばれてmetadata.txtの内容を付加する。
これで変換ができました。モノクロで画像の大きさも小さくなるものですが、ファイルサイズはかなり大きくなります。
うまくいかないとき/エラーが気になる時
うちの環境で起きたエラーとその対処を書いておきます。
- pgmからpngへの変換が行われない
convert: unable to open image `./pgm/tmp-001.pgm': そのようなファイルまたはディレクトリはありません
が出ていました(他のメッセージに埋もれて)。このときpgmディレクトリにはtmp-000001.pgmをはじめとする連番ファイルがありました。これはpdftoppmコマンドが6桁の連番でファイルを吐いたのに対し、Rakefileが3桁の連番を期待したため。Rakefileの52行目にある「l << "#{dir}/tmp-#{'%03d' % i}.#{ext}"」の「03d」を「06d」に置き換える必要がありました。
- PDFのファイル名が日本語だとうまく動きませんでした。ファイル名をローマ字にして解決。
- xpdfパッケージのデフォルトはフォントマップの指定をちゃんとしていないようで、フォント周りのエラーがたくさん出ました(参考: http://d.hatena.ne.jp/reservoir/20071102/1193968393 http://hsdiary.blogspot.com/2006/10/ja-xpdf-font-problem-2.html)。
ちゃんと生成するようになる前に直しておいたので検証してないけど、PDFからは画像形式で切り出すのでフォント関係のエラーは無視できるはず。
- rake --trace で実行することで途中経過がわかりやすくなります。
こんなところでしょうか。
調整
調整をあまり詰めてもしょうがないですが、ちょっとしたいじり方です。
- 出来上がりが気に入らないときは、途中のファイルをいじることで以後のファイルを自動で更新してくれる。
- 本文だけのギリギリのイメージを作りたいときは、Rakefileの「TOP = 250」「BOTTOM = 100」「LEFT = 50」「RIGHT = 50」の各数字を大きくすることで調整する。逆に最初から本文が侵食されているような場合には数字を小さくする。
- 表紙などのように、真ん中に1行だけあるページは余白が落とされると文字が巨大になってしまう。雰囲気を残したいなら convert ./pgm/tmp-000001.pgm -resize 720 ./png/tmp-000001.png のようにリサイズだけするとよいかも。
文庫本スキャンの例
追記。Scan Snap S1500を使い、いつもの設定でスキャンしたもの。カラーのPDFを表示しています:
文字が薄いのはコントラストを上げることで改善します。でもそうすると今度は紙の色を反映してバックが暗くなるし、余白が大きく文字が小さいので読む気になりません。
これに対して、同じスキャナでモノクロスキャンしたものをKindlizerをかけると:
これでも元の文庫本よりフォントが1割ほど小さくなってますが*1、普通に読めます。
この差は大きい!
もう少し大きいハードカバーの場合でも、文字詰めはあまり変わらないので、ほとんどこのようなイメージで読めると思います。うちのKindle3では感動的なほどちゃんと読めるようになりました。たださんに感謝いたします。
追記。上の写真は幅720のランドスケープ用PDFをポートレートで表示して「わーいわーい!これなら読める!」と喜んでいたのでした。ちゃんとSIZE = '560x735'で作ると、もっとキレイでした。Kindleのスクリーンショット機能もわかったので(↑+ALT+G)晒します。
当初のもの:
560x735で作ったもの:
ぜんぜん違いますね!
*1:一番上にある文字の上端から一番下にある文字の下端まで実測で122mm→110mm