FreeBSDとKindlizerで黒いPDFができる

ただただしさんが書かれたKindlizerというツールがあります。自分でスキャンしたPDFファイルを、Amazon KindleをはじめとするグレイスケールのE-Inkブックリーダーに最適化するものです。

このKindlizer、初めて使おうとするとちょっとわかりにくいので、初心者向けに特化したドキュメントとしてKindlizerの使い方というエントリを書きました。今回のは最適化オプションにまつわる話です。

KindlizerのREADMEを見ると、

以下の環境変数を指定すると、それぞれフェーズ2(ppmpngを行うconvertコマンド)とフェーズ3(png→pdfを行うsam2pコマンド)にオプションを追加できます:

  • KINDLIZER_PHASE2_OPT: convertコマンドへのオプション(推奨は「-depth 4 -deskew 40% -sharpen 5」)
  • KINDLIZER_PHASE3_OPT: sam2pコマンドへのオプション(上記PHASE2で「-depth 4」を指定しない場合に「-c:jpeg」を指定

convertコマンドのいくつかのバージョンでは「-depth 4」がサポートされていないため、標準では採用していませんが、サポートされている場合には非常にコンパクトなPDFファイルを生成できるため、強く推奨します。また、傾き補正のされていないPDFをソースにした場合に、-deskewオプションをつけることでより精度の高いトリミングができるようになるため、これも推奨します。

という記述があります。要するに、-depth 4というオプションを使いたいけど使えない場合がある、ということです。これはもともと、ImageMagick 6.6.6-0から6.6.9-9に入ってるgrayオプションが動かないconvertコマンドへの対策だそうです。

ところがオレの使ってるFreeBSD 8.2Rのportsに入ってるsam2pも、"convert -depth 4"で作ったpngファイル(これ自体はちゃんと読めるもの)をpdfファイルに変換したときに真っ黒なページを作ってくれちゃうという問題があり、やはりこの"-depth 4"が使えませんでした。

この真っ黒なページ、よく見ると文字が濃い黒でうっすら浮かび上がってます。どうやら背景色がおかしいようです。KindlizerのRakefileにはconvertコマンドのオプションとして"-type Grayscale -background white"がしてあります。これで背景を黒にしてしまうのは何か行き違いがある感じ。

この問題はsam2pのせいに見えます。sam2pの-j:warnオプションで警告を全部表示してみたときに:

$ sam2p -j:warn png/tmp-001.png 001.pdf
This is sam2p 0.49.
Available Loaders: PS PDF JAI PNG JPEG TIFF PNM BMP LBM XPM PCX TGA.
Available Appliers: XWD Meta Empty BMP PNG TIFF6 TIFF6-JAI JPEG-JAI JPEG PNM XPM PSL1C PSL23+PDF PSL2+PDF-JAI P-TrOpBb.
sam2p: Warning: check_rule: unsupported /Transparent+ for /PDF*
sam2p: Warning: buildProfile: ^^^ thus ignoring impossible OutputRule #32
sam2p: Warning: check_rule: unsupported /Transparent+ for /PDF*
sam2p: Warning: buildProfile: ^^^ thus ignoring impossible OutputRule #33
sam2p: Warning: check_rule: unsupported /Transparent+ for /PDF*
sam2p: Warning: buildProfile: ^^^ thus ignoring impossible OutputRule #34
sam2p: Warning: check_rule: unsupported /Transparent+ for /PDF*
sam2p: Warning: buildProfile: ^^^ thus ignoring impossible OutputRule #35
sam2p: Warning: check_rule: unsupported /Transparent+ for /PDF*
sam2p: Warning: buildProfile: ^^^ thus ignoring impossible OutputRule #36
sam2p: Warning: check_rule: unsupported /Transparent+ for /PDF*
sam2p: Warning: buildProfile: ^^^ thus ignoring impossible OutputRule #37
sam2p: Notice: PNM: loaded alpha, but no transparent pixels
sam2p: Notice: job: read InputFile: png/tmp-001.png
sam2p: Notice: writeTTT: using template: p02bb
sam2p: Notice: applyProfile: applied OutputRule #18
sam2p: Notice: job: written OutputFile: 001.pdf
Success.
$

という具合に透過性についての警告が出てるからです。しかしsam2pのバグ情報などは出ておらず、強制的に白背景にするにもREADMEの記述がちょっと理解できませんでした。"-s:gray4"みたいなオプションまでは見つけたけど動作は変わらず。いろいろググったけど情報があまり無くて行き詰まり。

とはいうものの、sam2pは必須ではありません。convertコマンドでもpngからpdfの変換は可能で、この場合は4bitグレイスケールでも真っ黒なPDFにはなりません。sam2pを使うよりファイルサイズは2割くらい大きくなりますが、4bitグレイにした時点で半分になってるので、元の6割くらいには圧縮できます。

とりあえずこれを使いましょう。変更部分はRakefileのpng2pdfにある"sam2p -j:quiet"を"convert"に書き換えるだけ。

def png2pdf( png, pdf )
        sh "convert #{ENV['KINDLIZER_PHASE3_OPT']} #{png} #{pdf}"
end

現時点ではこんなもんかな。