hnakamur’s blog

ものすごい勢いで忘れる私のために未整理でもいいからとりあえずメモ

2009-10-29

裁断機で本を切断してScanSnapでとりこんだPDFを画像ファイルにばらしてImageMagickで加工して再度PDFにしてみた

裁断機で本を切断してScanSnapで取り込むまで

前段階として裁断機で本を切断してScanSnapで取り込むところは、中身を捨てずに空間をすてる。漫画も本も iPhone に入れる全工程 | Lifehacking.jpと同じです。私は裁断機はPLUS PK-513を使っていて、ScanSnapはfi-5110E0Xです。

読み込む設定ですが、解像度は以前はスーパーファインにしてましたが、最近は容量削減のためファインにすることが多いです。白黒/カラーは自動判定にはせず切り替えて使います。白黒はモノクロ2値なのでグレースケールの書籍の場合はカラーにします。

また表紙カバーは別途フラットヘッドスキャナで取り込んでPDFファイルにしておきます。

PDFファイルの連結

表紙カバーと本体と裏表紙のPDFを連結して一旦1つのPDFにします。

Linuxだとpdftk - the pdf toolkitをつかえばよさそうです。私はMacBookを使っているのでMacPortsでインストールを試みたのですが、Install fails for gcc42 - libgfortran.a has no symbols?!と同じ問題にひっかかってインストールできていません。代わりに[mac] コマンドラインからpdfを結合する - Hirameki Inspirationで紹介されている方法を使っています。

/System/Library/Automator/Combine PDF Pages.action/Contents/Resources/join.py --output out.pdf in1.pdf in2.pdf in3.pdf ...

PDFファイルをページ毎に画像に分割

Apache PDFBox - Java PDF LibraryというJava向けのPDFライブラリ(以前はpdfbox.orgだったのですが最近Apacheのインキュベータに入ったようです)のExtractImageというクラスを利用します。事前にJavaのランタイムのインストールが必要です。旧バージョン0.7.3を使う場合は以下のコマンドを実行します。

java -cp PDFBox-0.7.3/lib/PDFBox-0.7.3.jar org.pdfbox.ExtractImages foo.pdf

実行するとカレントディレクトリにIm1-1.jpg, Im2-2.jpg, ...という具合に画像ファイルが作られます。JPEGになるはカラーで取り込んだ場合の話で、白黒の場合はTIFFファイルになります。この後の手順で扱いやすいようにディレクトリを作ってそちらに移動しておきます。もちろん、そもそも先にディレクトリを作っておいてそちらにバラしてもよいです。

ページごとの画像ファイルを加工

加工の目的

斜めになってしまったページを真っすぐにしたい

ScanSnapで取り込んだ画像は私のやり方が下手なのかもしれませんが、たいてい微妙に斜めになってしまいます。しかもページ毎に傾き度合いがばらついてしまいます。ScanSnapにも傾き補正機能がついているのですが、相当傾いていないと反応しないのと、ページ内に斜めの直線があると誤反応して斜めになってしまうことがあったので、結局使っていません。ちょっとぐらいの傾きは気にしないと割り切ったほうがいいと思いつつ、いつか綺麗にそろえたいと常々思っていました。Kindle DXで見ると特に気になってしまうんですよね、これが。

ファイルサイズを削減したい

グレースケールの本でも白黒でスキャンするとモノクロ2値になってしまってグレーの箇所が汚くなるのでカラーでスキャンしていますが、その後画像をグレースケールにするとかして少しでも容量を削減したい。ただしできるだけ見た目は綺麗に保ちたい。

画質を上げたい

カラーで取り込むとJPEGになるためか、文字の部分も色ムラができてKindle DXで見るときに、読めなくはないけど美しくない。一方、白黒で取り込んだTIFFはかなり美しくてみていてほれぼれします。でもグレースケールの本を白黒で取り込むと図とかでグレーの部分がきたなくなってしまうので、カラーで取り込まざるをえない。そこでJPEGを加工して少しでも綺麗にしたい。ただ、私の画像加工のスキルが低くて今はたいしたことができていません。

ImageMagickで加工

加工の仕方を試行錯誤することになるので手動だとやり直すのが大変なので、コマンドラインで実行できるImageMagickを使います。RubyのRakefileを書いてそこからImageMagickのconvertコマンドを実行するようにしてみました(RMagick使ったほうがいいかとも思いましたがImageMagickとRMagickのマニュアルを両方読むのが面倒だったので直接コマンドを実行することにしてしまいました)。

INPUT_DIR='./orig'
OUTPUT_DIR='./output'
PDF_OUTPUT_DIR='./output_pdf'

COVER_PAGE_WIDTH = 1710
COVER_PAGE_HEIGHT = 2444
PAGE_WIDTH = 1115
PAGE_HEIGHT = 1632

# page => [angle, x, y, type]
ADJUSTS = {
  1 => [0, 0, 0, :cover],
  2 => [0, 0, 0, :cover],
  3 => [0, 85, 42, :page],
  4 => [0, 110, 42, :page],
  5 => [0, 110, 42, :page],
  6 => [-0.27, 120, 42, :page],
  7 => [0.27, 100, 42, :page],
  8 => [-0.29, 100, 42, :page],
...(略)...
  1263 => [0.16, 100, 42, :page],
  1264 => [-0.16, 100, 42, :page],
  1265 => [0, 0, 0, :cover],
  1266 => [0, 0, 0, :cover],
};

task :conv do
  page = ENV['page'].to_i
  convert_page(page)
end

task :conv_all_pages do
  ADJUSTS.keys.sort.each {|page| convert_page(page)}
end

task :pdf_all_pages do
  ADJUSTS.keys.sort.each do |page|
    jpg_file = "#{OUTPUT_DIR}/%04d.jpg" % page
    pdf_file = "#{PDF_OUTPUT_DIR}/%04d.pdf" % page
    sh "convert #{jpg_file} #{pdf_file}"
  end
end

def convert_page(page)
  in_file = "#{INPUT_DIR}/Im#{page}-#{page}.jpg"
  out_file = "#{OUTPUT_DIR}/%04d.png" % page
  deg, x, y, type = ADJUSTS[page]
  case type
  when :cover
    w = COVER_PAGE_WIDTH
    h = COVER_PAGE_HEIGHT
    sh "convert #{in_file} -set option:distort:viewport #{w}x#{h}+#{x}+#{y} +distort SRT #{deg} -quality 50% -density 200 #{out_file}"
  when :page
    w = PAGE_WIDTH
    h = PAGE_HEIGHT
    #sh "convert #{in_file} -set option:distort:viewport #{w}x#{h}+#{x}+#{y} +distort SRT #{deg} -quality 50% -colorspace Gray -density 200 #{out_file}"
    #sh "convert #{in_file} -set option:distort:viewport #{w}x#{h}+#{x}+#{y} +distort SRT #{deg} -sharpen 0x1 -density 200 -normalize -colors 2 #{out_file}"
    #sh "convert #{in_file} -set option:distort:viewport #{w}x#{h}+#{x}+#{y} +distort SRT #{deg} +repage -density 200 -normalize -colors 2 #{out_file} && open #{out_file}"
    sh "convert #{in_file} -set option:distort:viewport #{w}x#{h}+#{x}+#{y} +distort SRT #{deg} +repage -density 200 -normalize -colors 2 #{out_file}"
  end
end

傾き補正の角度は元の画像ファイルをプレビューで開いてPixelStickというMac用のソフトで測っています。

ターミナルを2つ上げて1つはvimでRakefileを編集し、1つはrakeを実行するという感じでパラメータを調節しては変換して結果を見てというのをくり返します。このときはconvertした後openで結果を開くようにしておくとプレビューが開いて表示されるので手間が省けて便利です(コメントアウトしてあるshの行の最後)。ページ数の分だけひたすら繰り返すので、キーストローク数を最小にして効率を上げるのが重要です。私はCommand+TABでプレビューとターミナルを切り替え、ターミナルの2つのウィンドウはCommand+`(デフォルトはCommand+F1ですが変更しています)で切り替えています。

convertの引数は未だ試行錯誤中でこれがベストというのは見つけられていません(というよりImageMagickの使い方を勉強中です。オプションが多くて…)。

加工した画像を連結してPDFを作成

だいたい満足いくように各ページの画像を加工できたら、再び連結してPDFにします。ImageMagickを使ってconvert *.jpg out.pdfとするとすごく時間がかかるので、各ページごとにconvertでJPEGをPDFに変換して、上記の手順でPDFを連結します。

というわけで、相当手間と時間がかかるのですが、ページ毎に大きく傾いていたのがほぼ真っすぐになってKindle DXでも気分よく読めます。ですので苦労するだけのことはあります。

ブログ アーカイブ