日中は厳しい残暑が続くものの、朝夕は多少過しやすくなり、夜の時間もずいぶん長くなってきました。「 読書の秋」への準備、というわけでもありませんが、授業で使う参考資料をまとめて自炊した勢いで、本棚に眠っていた重い本も何冊か電子化してみました。
それらの中には数百ページのハードカバー本も含まれます。ハードカバー本は値段も高く、作りもしっかりしているので、分解することに心理的、物理的な抵抗はあったものの、思いきって電子化してサイズや重さの制約から解き放ってみると、以前よりもずっと頻繁に目を通せるようになりました。移動中や外出先での空き時間に、数百ページもあるハードカバー本を手軽に読めるのは、電子書籍ならでは魅力でしょう。
しかし、自炊電子書籍が増えてくるにつれ、それらをもっと読みやすくできないだろうか、と思うようになりました。たとえば、紙の本では製本上の都合もあって、本文の周囲にはかなり広い余裕(マージン)が取られています。これらマージンは紙の本では必須だったのでしょうが、電子書籍には不要で、無い方が本文部分を大きく表示できそうです。
図1 スキャンした元ページの表示
ComittoN等の電子書籍ビューワでは、画面サイズに合わせてページを自動的に拡大縮小するズーム機能が用意されているので、その機能を使えば本文部分のみで画面一杯使うことも可能です。しかし、その場合でもページごとに表示範囲を微調整する必要はありますし、2ページを見開きで表示したい、といった場合は、ページ単位でのズーム機能は役に立ちません。
自炊時にあらかじめマージン部分をスキャン範囲外にすることも考えましたが、「 マージンの大きさ」というのも元の紙のページが持っていた情報として保存したいものです。そこで、大元のスキャンデータは従来通りページ全体を取ることにして、そこから電子書籍用により適したデータを生成する方法を考えてみました。
画像処理ツールnetpbm
GIMPのような画像処理ツールを使えば、マウス操作のみでページの本文部分を切り出したり、画像のサイズや解像度を変更することができます。
しかし、1枚の写真を修正するならともかく、数百ページを超えるような電子書籍の各ページを手作業で修正することは現実的ではありません。そこでコマンドラインから使える画像変換・編集ソフトであるnetpbm というツールを使ってみました。
netpbm は多種多様な画像形式を相互変換するツールや、画像に対してさまざまな処理を加えるためのツールをまとめた、画像処理用ツールの一大パッケージです。
最近では「コンピュータ用の画像形式」と言うと、写真向けのJPEG 形式かCG等でよく使われるPNG 形式が主流で、Web上で目にする画像は、たいていどちらかの形式になっているようです。しかし、WindowsやOS/2ではBMP 形式が標準の画像形式ですし、MacintoshではPICT 形式がOSに組み込まれた標準の画像形式でした。一方、X Windows Systemでは白黒2値のXBM 形式やカラーに対応したXPM 形式がアイコンや背景用の画像形式として広く利用されてきました。最近ではWeb上のアニメ程度にしか利用されていないGIF 形式も、元々はパソコン通信用に開発された画像形式でしたし、スキャナやFAXなどではTIFF 形式も広く利用されています。
netpbmはこれらメジャーな画像形式を含め、最近ではほとんど使われなくなった画像形式もサポートしている、歴史的な重みを感じさせるツールです。
多数の画像形式に対応する場合、「 BMP形式をPICT形式に変換するツール」「 JPEG形式をXPM形式に変換するツール」という風に、それぞれの形式を一対一で変換しようとすると,膨大な数のツールが必要になります。そのためnetpbmでは、中間的な画像形式 を定めて、各画像形式を中間的な画像形式に変換するためのツールと中間的な画像形式から各画像形式に変換するためのツールを用意することで、組み合わせの爆発的な増加を回避しています。
たとえば先に紹介した8種(JPEG、PNG、BMP、PICT、XBM、XPM、GIF、TIFF)の画像形式だけを考えても、一対一で変換するツールを作ろうとすれば BMP->PICT、PICT->BMP、JPEG->XPM、XPM->JPEG…… のように8×7=56種類のツール が必要になります。一方、中間形式を用いて各形式と中間形式を変換するようにすれば、各形式ごとに中間形式と相互変換するためのツールを用意すればいいので、8×2=16種類のツール で済むことになります。
新しい画像形式をサポートする際も、一対一で変換しようとすると、新しい形式と既知の形式を相互変換するために8×2=16種類のツールを追加する必要がありますが、中間形式を用いれば、中間形式と新しい画像形式を相互変換するための2つのツールを書くだけで済みます。
実のところ、netpbmの中間形式にはフルカラー用のPPM (Portable Pixel Map)形式、グレースケール用のPGM (Portable Gray Map)形式、白黒2値のみのPBM (Portable Bit Map)形式の3種類が用意されているので、相互変換はもう少し複雑になります。また、最近ではこれらの形式と上位互換性を持つPAM (Portable Arbitrary Map)という新しい形式も提案され、この形式でコマンド類を整理し直そうとしているようです。
画像の拡大縮小や切り出し、強調といった処理も、それぞれの画像形式ごとに対応しようとすれば大変な作業になりますが、中間形式を介することにしておけば、中間形式に対して処理するツール を開発するだけで、それぞれの画像形式に直接対応する必要はなくなります。
netpbmはこういうアイデアで開発された300を超える小さなツール (コマンド)を集めたソフトウェアパッケージで、PC上で利用されているたいていの画像形式を処理することができます。
netpbmパッケージに含まれているツールは、数が多すぎて全体を把握しづらくなっているものの、基本的にjpegtopnm やgiftopnm のように"XXXtopnm"になっているのがnetpbmの中間形式(カラーならばPPM、グレースケールならばPGM)に変換するためのツールで、pnmtojpeg やpnmtopng のように"pnmtoXXX"になっているのが中間形式から各画像形式に変換するためのツールです。
一方、画像サイズを変更するpnmscale や色数を調整するpnmquant 、画像の角度を変えるpnmrotate のように、"pnmXXX"になっているのは中間形式の画像を操作するためのツールです。
なお、これらの名称に含まれている"pnm"とは"Portable aNy Map"の略で、netpbmが採用している中間形式(PBM/PGM/PPM)の総称 であって、PNMと言う画像形式が存在するわけではありません。そのためpnmscaleやpnmquantのように"pnm"を名前の一部に持つツールは、PBM/PGM/PPMの各形式を区別することなく操作できます。それに対し、pgmenhance やpbmclean のように"pgm"や"pbm"を名前の一部に持つツールは、それぞれの画像形式を前提にしており、異なる形式のデータを扱う場合は事前に変換処理をしておく必要があります。
netpbmとコマンドラインからの操作
netpbmに含まれている各ツールは、UNIXの基本哲学である「ソフトウェア・ツールズ 」の考え方で設計されています。すなわち、全てのツールはファイルか標準入力からデータを読み込み、処理した結果は標準出力に出力します。こうすることで、各ツールの出力と入力をUNIXのパイプ機能("|")を使って連結し、処理をどんどん追加してゆくことができます。
たとえば、JPEG形式の画像をサイズを縮小してGIF形式に変換したい場合は、JPEG形式を中間形式に変換(jpegtopnm )し、中間形式でサイズを変換(pnmscale )し、GIF形式の制限である256色まで減色(pnmquant )した上で、GIF形式に変換(ppmtogif )する、という手順になります。各手順をそれぞれ1つのツール(コマンド)が担い、それらをパイプで接続して必要な処理を実現するわけです。
$ jpegtopnm photo1.jpg | pnmscale 0.5 | pnmquant 256 | ppmtogif > photo1.gif
処理しなければいけない画像が1枚だけならば、キーボードからこれだけのコマンドを入力するよりもGIMP等の画像処理ツールを利用する方が簡単でしょう。しかし、netpbmの実力は同じ作業を何度も繰り返す際に発揮されます。
最初に述べたような、スキャン済みの画像データからマージンを切り取る作業を考えてみましょう。netpbmの画像切り出しツール(pamcut )では、元の画像の左端と上端からのオフセットと、切り出したい画像の幅と高さを指定する必要があるので、まずは適当なページをGIMPで開いて、どのあたりを切り出せばいいかを検討します。
図2 GIMPを使った切り出し範囲の選択
GIMPの矩形ツールを使ってだいたいのあたりを取ったところ、左端から160ドット、上端から120ドットほどオフセットをかけて、1400ドット×2080ドットくらいで切り出せばよさそうです。
実際にこのパラメータで10ページほど切り出して問題ないか確認してみます。
$ mkdir Temp
$ for i in page_001[0-9].jpg ; do
> testpage=`echo $i | sed "s/jpg/png/"`
> jpegtopnm $i | pamcut --left 160 --top 120 --width 1400 --height 2080 > Temp/$testpage
> done
jpegtopnm: WRITING PGM FILE
jpegtopnm: WRITING PGM FILE
...
ここで使っているpamcutはnetpbmの新しいPAM(Portable Arbitrary Map)形式を操作するためのコマンドで、"pnm"の接頭辞を持つコマンド群同様、netpbmの中間形式(PPM/PGM/PBM)を区別せずに操作することができます。
確認のために、異なるページを切り出した結果をGIMPで確認してみると、ほぼ目的通りの範囲を切り出せているようです。
図3 pamcutで切り出した範囲の確認
切り出し範囲が確定したので、今度はページをまとめて処理してみます。先の例ではページ数の指定にシェルの正規表現 (page_001[0-9].jpg
)を使いましたが、切り出したいページがあらかじめ決まっている場合は、連番を出力するseq というコマンドを使ってページ番号を生成する方が簡単です。たとえば、7ページから51ページまでを切り出したい場合、"seq 7 51
" とすれば、7から51までの連番が出力されます。
$ seq 7 51
7
8
9
...
51
このseqコマンドの出力をbashのfor機能 と組み合わせれば、各ページに対する処理を繰り返し実行することができます。その際は、seqコマンドの「実行結果」をforループで受けることになるので、seqコマンドの周囲を` (バッククォート)で括ることを忘れないでください。
まずはseqの使い方の例として、処理したいページのファイル名を生成してみましょう。ファイル名のページ数は4ケタに揃えているので、seqの出力もケタを揃えるために-w オプションを指定しています。
$ for i in `seq -w 7 51` ; do
> page="page_00"$i".jpg"
> echo $page
> done
page_0007.jpg
page_0008.jpg
...
page_0051.jpg
ファイル名を生成できるようになったので、実際の切り出し処理を組み込んでみます。ただし、先のパラメータを使うと、切り出した後のページは1040×2080ドットになりますが、電子書籍リーダーに使っている旧Nexus7は画面幅が800ドットなので、70%くらい縮小をかける(pamscale 0.7 )と共に、少しエッジを強調して文字を目立つように(pgmenhance -5 )した上で、JPEG形式に戻して(pnmtojpeg )います。
$ for i in `seq -w 7 51` ; do
> page="page_00"$i".jpg"
> jpegtopnm $page | pamcut --left 160 --top 120 --width 1400 --height 2080 | \
> pamscale 0.7 | pgmenhance -5 | pnmtojpeg > Temp/$page
> done
jpegtopnm: WRITING PGM FILE
jpegtopnm: WRITING PGM FILE
jpegtopnm: WRITING PGM FILE
...
こうして切り出した画像をcomixで見開き表示してみると、以前は目立っていた本文周辺のマージンが無くなって、本文がよりはっきりと読めるようになりました。
図4 マージンを切り抜いたページ画面
旧Nexus7上のComittoNでは、元からあるズーム機能のおかげでマージンが無くなったメリットはそう強くは感じられませんが、ページめくりの際に表示位置を微調整する必要がなくなったのは快適です。
ちなみに今回の操作例に使ったのは、田川健三『新約聖書 訳と注1 マルコ福音書/マタイ福音書』( 作品社)を自炊したデータです。
この本は、タイトル通り新約聖書の翻訳のひとつですが、注釈等をほとんど付けない伝統的な翻訳版聖書とは異なり、訳文のページ数の10倍くらいはある詳細な訳注に、歴史や背景の解説から新約聖書学の知見の紹介、翻訳上の問題点の指摘、さまざまな写本間の正文批判の議論など、非キリスト教徒な筆者が読んでもめっぽう面白い本になっています。
しかしながら、ハードカバーで880ページほどもある大著で、重さを計ってみると1350gぐらいありました。
図5 ハードカバー本の重さは1350g
さすがにこのサイズと重さになると、カバンに入れておいて移動中の空き時間に読むとか、ベッドに寝っころがって眠気が来るまであちこち拾い読みする、というわけにもいかず、面白い本だとは思いつつも、本棚で埃をかぶりがちになっていました。
そこで思いきって自炊の対象にしてみたところ、今までは重いと思っていた500g弱の旧Nexus7が、ずいぶん軽く感じるようになりました(笑) 。
前回は物理的な存在としての「本」の寿命の長さを評価しましたが、物理的な存在には「重さ」と「体積」が伴ない、着実に床や本棚を侵食して行きます。「 本」を「アトム(物質) 」として扱うべきか「ビット(情報) 」として扱うべきか、答えは簡単には見つからないようです。