ruby で RMagick を利用して画像処理する

シェアする

Ruby で画像処理を行うには RMagick を利用するのが良いらしい。画像処理のためのソフトである ImageMagick を Ruby で操作するためのもののようだ。

Sponsored Links

RMagick のインストール

$ sudo apt-get install imagemagick libmagickwand-dev
$ gem install rmagick

$ irb
irb(main):001:0> require 'RMagick'
=> true

これでインストールは OK

RMagick を使ってみる

適当に動かしてみる。

画像の読み込みと保存

irb(main):002:0> require 'RMagick'
=> true
irb(main):003:0> image = Magick::Image.read('z3.png')
=> [z3.png PNG 804x477 804x477+0+0 DirectClass 8-bit 862kb]
irb(main):004:0> image = Magick::Image.read('z3.png').first
=> z3.png PNG 804x477 804x477+0+0 DirectClass 8-bit 862kb

Magick::Image.read メソッドは Array を返すので最初の要素を .first で取得している。[ ] で囲われているのがわかる。

バイナリから Image を作成するには以下のように from_blob を使用する。

# irb じゃなくて実際に利用しているコードから抜粋。
require 'cgi'
require 'RMagick'

cgi = CGI.new("html3")
imagedata = cgi.params['imagedata'][0].read
image = Magick::Image.from_blob(imagedata).first

write メソッドを利用する事で画像を保存できる。

irb(main):008:0> image.write('newfile.png')
=> z3.png=>newfile.png PNG 804x477 804x477+0+0 DirectClass 8-bit 600kb

画像フォーマットの変換

画像フォーマットを変換する時は、write でファイル名を渡す際に拡張子を変えてやるだけで勝手に変換してくれる。

irb(main):009:0> image.write('newfile.jpeg')
=> z3.png=>newfile.jpeg PNG 804x477 804x477+0+0 DirectClass 8-bit 128kb
irb(main):010:0> image.write('newfile.gif')
=> z3.png=>newfile.gif PNG 804x477 804x477+0+0 PseudoClass 256c 8-bit 280kb

PNG と出てくるので不安になるが od コマンドで確認してみるとちゃんと変換されているようだ。

$ od -tx1c z3.png | head -n 2
0000000  89  50  4e  47  0d  0a  1a  0a  00  00  00  0d  49  48  44  52
        211   P   N   G  \r  \n 032  \n  \0  \0  \0  \r   I   H   D   R
$ od -tx1c newfile.jpeg | head -n 2
0000000  ff  d8  ff  e0  00  10  4a  46  49  46  00  01  01  02  00  26
        377 330 377 340  \0 020   J   F   I   F  \0 001 001 002  \0   &
$ od -tx1c newfile.gif | head -n 2
0000000  47  49  46  38  39  61  24  03  dd  01  f7  00  00  02  03  02
          G   I   F   8   9   a   $ 003 335 001 367  \0  \0 002 003 002

画像の拡大縮小

RMagick で拡大縮小を行うメソッドは複数ある。

簡単にまとめてみる。

resize 画質は良いがファイルサイズは大きくなる
scale 画質は悪く、ファイルサイズも小さくなる
thumbnail ファイルサイズは大きくなるが実行速度は速い
sample 実行速度は早くサイズも小さいが中間色を作らないので画質は悪い

どのメソッドも float を引数に取るので以下のように書ける。

irb(main):003:0> image.resize(0.1)
=> z3.png PNG 804x477=>80x48 80x48+0+0 DirectClass 8-bit
irb(main):004:0> image.scale(0.1)
=> z3.png PNG 804x477=>80x48 80x48+0+0 DirectClass 8-bit
irb(main):005:0> image.sample(0.1)
=> z3.png PNG 804x477=>80x48 80x48+0+0 DirectClass 8-bit
irb(main):006:0> image.thumbnail(0.1)
=> z3.png PNG 804x477=>80x48 DirectClass 8-bit
irb(main):007:0> image.resize!(0.1)
=> z3.png PNG 804x477=>80x48 80x48+0+0 DirectClass 8-bit
irb(main):008:0> image.resize!(0.1)
=> z3.png PNG 804x477=>8x5 8x5+0+0 DirectClass 8-bit

! をつけると破壊的メソッドとなるらしい。オブジェクトの中身を変更してしまうようだ。上記例だと最後の resize 二回だが実行する都度画像がどんどん小さくなっていってるのが分かる。

pixel 指定で画像のサイズを変更する際は resize_to_fit メソッドを利用すると良い。

irb(main):010:0> image.resize_to_fit!(80,48)
=> z3.png PNG 804x477=>80x47 80x47+0+0 DirectClass 8-bit

画像の一部を切り取る

画像の一部を切り取るには crop メソッドを利用する。以下のように3種類引数の渡し方がある。

img.crop(x, y, width, height) -> image
img.crop(gravity, x, y, width, height) -> image
img.crop(gravity, width, height) -> image

RMagick 2.12.0: class Image (class methods and instance methods a-d):

irb(main):014:0> image.crop(500,50,300,350).write("croped.png")
=> z3.png=>croped.png PNG 804x477=>300x350 804x477+500+50 DirectClass 8-bit 188kb
# 左上から500px,50px の地点より 300x350 の画像を生成

irb(main):019:0> image.crop(Magick::CenterGravity, 400, 300).write("cropped.png")
=> z3.png=>cropped.png PNG 804x477=>400x300 804x477+202+88 DirectClass 8-bit 212kb
# 中央基点にして 400x300 の画像を生成

簡単に扱えて便利だ。

Sponsored Link

シェアする

フォローする