Rubyで画像フォーマットを変換するスクリプトを作ろう

これは Ruby逆引きレシピAdvent Calendar の参加エントリです。
12月20日担当分となります。

やりたいこと

  • 画像をpdfにさくっと変換できる環境がほしいの!
  • ついでに他のフォーマットにも変換できたらいいな

きっかけ

会社での以下のやりとりによる。
休憩中の会話@職場

つかったもの

ライブラリ

  • ImageMagick
  • RMgagick

参照レシピ

  • 002:RubyGemsを使ってパッケージをインストールしたい
  • 007:リファレンスマニュアルを参照したい
  • 012:irb起動時に読み込むライブラリを指定したい
  • 013:irbでTab補完やシンタックスハイライトをしたい
  • 014:irbの実行結果をハッシュロケット形式で式の横に表示したい
  • 153:画像にエフェクトをかけたい

環境準備

ImageMagickをインストール

私の環境はFedora13であります。

# yum install ImageMagick-devel

これだけインストールされました。

Package(s) data still to download: 553 k
(1/4): ImageMagick-devel-6.5.8.10-6.fc13.i686.rpm | 88 kB 00:00
(2/4): ghostscript-devel-8.71-16.fc13.i686.rpm | 43 kB 00:00
(3/4): jasper-devel-1.900.1-15.fc13.i686.rpm | 374 kB 00:00
(4/4): lcms-devel-1.19-1.fc13.i686.rpm | 49 kB 00:00

RMagickをインストール

# gem install rmagick
実行すると

「No definition for XXXXXXX(パッケージ名のようです)」

のメッセージが大量に出ました。あせります。
調べて見たところ、rdocが足りないらしい。ということで、rdocをインストール。
# gem install rdoc

…なんかでた。

RDoc 2.5 did not save method parameters, so you should upgrade your rdoc-data
gem to a version >= 2.5.3.
To have ri data for core and stdlib you’ll need to:
gem install rdoc-data
then run:
rdoc-data –install
To have ri data for you gems you’ll also need to run:
gem rdoc –all –overwrite
If you don’t want to rebuild the rdoc for `gem server`, add –no-rdoc.
Successfully installed rdoc-2.5.11
1 gem installed
/usr/lib/ruby/gems/1.8/gems/rdoc-2.5.11/lib/rdoc/ruby_lex.rb:67: warning: parenthesize argument(s) for future version
Installing ri documentation for rdoc-2.5.11…
Installing RDoc documentation for rdoc-2.5.11…

rdoc-dataが古いよ、といわれているようなので、表示にしたがってupdate。
# gem install rdoc-data
# rdoc-data --install
# gem rdoc --all --overwrite

で、RMagickを入れ直し。
# gem uninstall rmagick
# gem install rmagick

Building native extensions. This could take a while…
Successfully installed rmagick-2.13.1
1 gem installed
/usr/lib/ruby/gems/1.8/gems/rdoc-2.5.11/lib/rdoc/ruby_lex.rb:67: warning: parenthesize argument(s) for future version
Installing ri documentation for rmagick-2.13.1…
Installing RDoc documentation for rmagick-2.13.1…

OK.成功しました。
warning: parenthesize argument(s) for future version
この警告は1.9系にするとでなくなるようですね。
むーん、はやく、Ruby1.9にしましょう…

簡単にいじってみる

とりあえずサムネイルを作ってみました。
このあたり、実際はirbで実行して確認しながらやっています。
この方が、間違えたらすぐにわかる&どう動いているかわかるので私にはよいみたい。
今回レシピ

  • 012:irb起動時に読み込むライブラリを指定したい
  • 013:irbでTab補完やシンタックスハイライトをしたい
  • 014:irbの実行結果をハッシュロケット形式で式の横に表示したい

あたりで、irb環境をカスタマイズできることをしりました。「超」快適です。
# 実はまだ014の設定はうまく行っていない

require 'rubygems'
require 'RMagick'
// 画像パス
path = "rmagick_sample.jpg"
// 処理したい画像を読み込む
img = Magick::ImageList.new(path)
// リサイズ
img.crop_resized!(100,100)
// 保存
img.write("#{path}_cropped.jpg")

さくっとサムネイルができました。

画像をpdfに変換しよう

ざっくりいうと、

  1. バイナリ型式で画像を読み込む
  2. 変換したいフォーマットを指定する
  3. 画像を出力する

という処理を行えば、フォーマットの変換が行えるようになっているらしい。
便利だなぁ。

対応しているフォーマットは以下で確認できます。
>> Magick.formats
けど多すぎてちゃんと読まずにすすみました。

// 元画像データを読み込む
blob = File.open('Cheetah.jpg').read
ilist = Magick::ImageList.new
// バイナリ型式で画像を扱う
ilist.from_blob(blob)
// 新しい拡張子を指定
ilist.format = "PDF"
// ファイル書き込み
File.open("rmagick_sample.pdf", "wb"){|f|
  f << ilist.to_blob
}

ちゃんとpdfファイルができた!!!

もうすこし便利にしよう

ファイルと拡張子が動的に変更できたら、いろんなフォーマットに変換できる!
ということで

  • ファイルを引数で指定できる
  • 拡張子を引数で指定できる

ようにしました。

// imageconv.rb
require "rubygems"
require "RMagick"
// 1つ目の引数はファイルパス
path = ARGV[0] 
//2つめの引数は変換したいフォーマット
format = ARGV[1]

blob = File.open(path).read
img = Magick::ImageList.new
img.from_blob(blob)
img.format = format.upcase
File.open("#{path.split(".")[0]}.#{format.downcase}", "wb"){|f|
  f << img.to_blob
}

こんな感じで実行すると同じディレクトリに変換されたファイルが出力されます。
$ ruby imageconv.rb rmagick_sample.png PDF

png→pdfにしてもファイルサイズがあまり圧縮されていないようではありますが、
きちんとフォーマットが変更されていました!
(画像も見れました!)

Ruby 逆引きレシピのよいところ

ちょっとした自分のための便利スクリプトを作るのって楽しいですね。

私はまだ、rubyの文法をきっちり覚えていないので、
やりたいことがまずあって、文法から何から調べながら進むことがほとんどです。

やりたいことがはっきりしているとき、Ruby 逆引きレシピは本当に便利です!
正直なところ、つい最近この便利さに気がつきました。
(文法は毎回リファレンスを見ながらちょっとずつ身につけています)

「これrubyでできるんじゃね?」脳を鍛えてきたいところです。

Ruby 逆引きレシピ すぐに美味しいサンプル&テクニック 232 (PROGRAMMER’S RECIPE)
島田 浩二 設樂 洋爾 村田 賢太 前田 智樹 谷口 文威
翔泳社
売り上げランキング: 67909

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください