Macで複数ページのpdfを一括でjpegにコマンドラインで変換する

本記事の目的は、Macで複数ページのpdfを一気にjpegに吐き出す操作を、端末から行うことです。有名な方法としては、Automatorを用いたものがありますが、自動化には不適なので、ここでは端末を使います。というかAutomatorよくわからん…。

目次

MacにおけるPDF→JPEG変換

OSXでpdfファイルをjpeg画像に変換しようと思ったら、標準のプレビューアプリを使うのが一番てっとりばやいです。しかしこれだと、1ページずつしか出力できず、とてもやっていられません。そこで複数ページを一括で変換する際は、Automatorを使用するやり方が有名なようです。ようです、というのは私はこのAutomatorの使い勝手がイマイチよくわからず、あまり使ったことがないからです。

せっかくのUNIXですから、自動化にうってつけなのはやはりコマンドラインだと思います。ということで、Macの端末上からpdfをjpegに変換する手順を書きます。おまけで、jpegをzipに圧縮します。さらにおまけで、一連の処理を自動化したRubyスクリプトも最後に付記します。

使用するソフトウェア

使用するソフトウェアはImageMagickPoppler。ImageMagickのcovertコマンドだけでもjpegにはできるのですが、なんだか画質が荒い。同様に、Popplerのpdftoppmコマンドにも、toppmといいながら-jpegオプションがあるのですが、これもちょっと荒い。調整することもできるのかもしれませんが、ヘルプを見てもちょっとわからず。結局、pdftoppmで一度ppmにした後、convertでjpegにするのが簡単でかつ綺麗でした(下図)。

スライド3

pdftoppm -jpeg と pdftoppm -> convert の比較

Homebrewがあることを前提に、以下のコマンドでインストールします。Homebrewがない場合はまずそのインストールから(「Homebrew — OS X 用パッケージマネージャー」より、コピペ一発でインストール可)。

$ brew install imagemagick
$ brew install poppler

参考:表示範囲 (CropBox) を考慮して PDF のサムネイルをつくる - Qiita

コマンドの実行

input.pdf を、output-NUMBER.jpg のように出力する場合、以下のように実行します。

$ pdftoppm input.pdf buf
-> buf-1.ppm, buf-2.ppm ... と出力される
$ convert *.ppm output.jpg
-> output-0.jpg, output-1.jpg ... と出力される
$ rm -f *.ppm
-> いらないppmはお掃除

さらに、以下でoutput.zipにします。

$ zip -r -m output.zip output*.jpg

jpgファイルが残るのが鬱陶しい場合は、-jオプションを付記すると、zip圧縮後、jpg画像が残りません。その他の注意点としては、ファイル名に空白が挟まると、ワイルドカードからの展開の仕方によってエラーが起きる可能性があります(通常は空白が区切りなので)。空白が含まれるファイルは多いので、なにかしらの対応が必要があるかもしれません(参考:「逆引きシェルスクリプト/スペースが含まれる文字列を1行として扱う方法 - Linuxと過ごす」)。

おまけ:一連の処理をまとめたRubyスクリプト

私はちょいちょいpdfを画像化することがあるので、一連の処理を簡単なRubyスクリプトにしています。そのスクリプトをおまけでつけておきます。OSXって最初からRuby入ってたかどうか覚えていませんが、Rubyが使えるなら以下のスクリプトをコピペして、pdfファイルを引数に渡して実行すると、pdfをjpgで固めたzipに変換します。以下スクリプト名をpdf2zip.rbとしたときの使用例。

$ ruby pdf2zip.rb test/*.pdf
-> testディレクトリ以下に出力されます。

以下ソースコード。

#!/usr/bin/env ruby
# coding: utf-8

require 'fileutils'

class Pdf2Zip
  def initialize(file)
    @target_path = file
    @name = File.basename(file, ".pdf")
    @dir  = File.dirname(file)
  end

  def to_zip
    files    = _pdf2jpg()
    zip_file = _jpg2zip(files)
  end

  def _pdf2jpg
    buf = "#{@dir}/#{@name}"
    norm_ppm = Dir.glob("#{Regexp.escape(buf)}*.ppm")
    system('pdftoppm',@target_path,buf)
    ppm_list = Dir.glob("#{Regexp.escape(buf)}*.ppm")
    ppm_list = ppm_list - norm_ppm
    files = Array.new
    ppm_list.each{|f|
      next if File.extname(f) != '.ppm'
      jpg_name = f.sub(".ppm",".jpg")
      system('convert',f,jpg_name)
      files.push(jpg_name)
    }
    FileUtils.rm(ppm_list)
    return files
  end

  def _jpg2zip(files)
    zip_file = "#{@dir}/#{@name}.zip"
    zip_ary = ['zip','-r','-m',zip_file] + files
    system(*zip_ary)
    return zip_file
  end

  def to_s
    p @target_path,@dir
  end
end

# subroutine
def pdf2zip(file)
    pdf_file = Pdf2Zip.new(file)
    puts file
    pdf_file.to_zip
end

def usage
  puts "Usage: $ ruby #{File.basename($0)} [FILES]"
  exit
end

# main
usage if ARGV.size == 0
usage if (ARGV[0] == '-h') or (ARGV[0] == '--help')
flist = ARGV.dup           if ARGV.size > 0
flist.each{|f| pdf2zip(f)  if '.pdf' == File.extname(f)}

ちなみに、私はzipをそのままcbzに変更することが多々有ります。その場合to_zip関数の最後の行に「FileUtils.mv(zip_file, zip_file.sub('.zip','cbz'))」を付記するなどで良いでしょう。

本サイトはUXを悪くするevilなGoogle広告を消しました。応援してくださる方は おすすめガジェット を見ていってください!
よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次