TL;DR
スキャナで書籍を自炊したPDFを加工するには、 今のところ以下の方法が良いとの結論に達しています。
背景
少し前に入手した ScanSnap iX500 でのスキャンにも慣れてきて、 幾つか漫画もスキャンしたのですが2つほど大きな不満がありました。 1つは栞が設定できないことで、 特定のエピーソードを読むのに先頭から順にページ送りするのは、 なんともダルい作業です。
もう1つは見開きのためのページレイアウト。 一般に漫画は右綴じなのですが、 iX500 に付属のソフトは左綴じしか出力できません。 作者渾身の見開きページがまったく再現できずに残念なことになってしまいます。
以上2点の不満を解決するためにスキャン後のPDFの加工を模索していました。 その結果、現時点における私にとっての最適解を以下で解説します。
解法
栞の追加
栞を追加するには PDFtk を使います。 リンク先からダウンロードしたファイルには色々なファイルが含まれていますが、 Windows で実行する際に必要なのは pdftk.exe と libiconv2.dll だけですので、 PATH の通った場所にコピーするのも良いでしょう。 私はそうしてます。
で、栞を追加するにあたり入力データとして、 以下のような栞定義ファイルを用意します。
BookmarkBegin
BookmarkTitle: タイトル1
BookmarkLevel: 1
BookmarkPageNumber: 1
BookmarkBegin
BookmarkTitle: タイトル1-2
BookmarkLevel: 2
BookmarkPageNumber: 3
内容から想像が付くでしょうが、Title
でラベルを、
Level
によって木構造のネストを、
PageNumber
によってリンクする先のページ番号を指定します。
日本語については必ずUTF-8で保存しましょう。
このようなファイルを bookmarks.txt と保存したら、
以下のコマンド例でPDFに栞として埋め込みます。
ココでは INPUT.pdf
が入力となる栞の無い PDF で、
OUTPUT.pdf
が栞が埋め込まれた出力となる PDF です。
$ pdftk INPUT.pdf update_info_utf8 bookmarks.txt output OUTPUT.pdf
右綴じ&見開き設定
右綴じ&見開きの設定はいくつか方法を試したのですが、 Perl の PDF::API2 がもっとも安定しました。 PDF::API2 は以下のように cpan を使ってインストールできます。
$ cpan
> install PDF::API2
実際に右綴じ&見開きを設定するのは以下のスクリプト (r2l.pl) を実行します。
例によって INPUT.pdf
が加工前のファイル名で、
OUTPUT.pdf
が加工後のファイル名です。
スクリプト中では固定値にしているので、適宜修正しましょう。
use PDF::API2;
$pdf = PDF::API2->open("INPUT.pdf");
$pdf->{'catalog'}->{'PageMode'} = PDF::API2::PDFName('UseOutlines');
$pdf->{'catalog'}->{'PageLayout'} = PDF::API2::PDFName('TwoPageRight');
$pref = $pdf->{'catalog'}->{'ViewerPreferences'} ||= PDF::API2::PDFDict();
$pref->realise();
$pref->{'Direction'} = PDF::API2::PDFName('R2L');
$pdf->{'pdf'}->out_obj($pdf->{'catalog'});
$pdf->saveas("OUTPUT.pdf");
ざっくり解説しますと、まず以下の行で栞をデフォルトで表示するようにしています。
$pdf->{'catalog'}->{'PageMode'} = PDF::API2::PDFName('UseOutlines');
次にこのブロックで、右綴じを設定してます。
$pref = $pdf->{'catalog'}->{'ViewerPreferences'} ||= PDF::API2::PDFDict();
$pref->realise();
$pref->{'Direction'} = PDF::API2::PDFName('R2L');
これは本来ならば $pdf->preferences()
メソッドでやれば良いことなのですが、
これを使うと設定して欲しくないモノも設定されてしまうので、
しかたなくその実装から必要な部分だけをコピーして使っています。
ここまでで右綴じ設定はできているのですが、 表紙も含めてスキャンしていた場合には表紙が1ページになってしまい、 見開きのページがズレてしまいます。 なので表紙だけは見開きにせず、 2ページ目以降を見開きで表示するための設定が次のコードです。
$pdf->{'catalog'}->{'PageLayout'} = PDF::API2::PDFName('TwoPageRight');
ちなみにですが左綴じで同じことをしたい場合には、
コレを TwoPageLeft
にすれば良いようです。
留意事項
PDF::API2 は相当に万能なので栞の埋め込みにも使えます。 しかし今回それをしていないのは、 栞の為に Perl のコードを書くのはダルいと判断したからです。 PDFtk のメタデータフォーマットは DSL の一種として成立しており、 栞のデータを入力するには適していると判断しました。 もちろん Perl で DSL を定義&解釈して、 PDF::API2 で埋め込むというのもありでしょう。 が、現時点においては DSL の実装が面倒なので PDFtk に甘えています。