Hatena::Grouprails-recipebook

Rails RecipeBookはてな版

書籍化を目標にRailsについて書いております。申し訳ありませんが禁無断転載でよろしくお願いします。

[記事一覧]

2007-12-10

[][] RMagickで画像を扱う 10:54  RMagickで画像を扱う - Rails RecipeBookはてな版 を含むブックマーク はてなブックマーク -  RMagickで画像を扱う - Rails RecipeBookはてな版  RMagickで画像を扱う - Rails RecipeBookはてな版 のブックマークコメント

お知らせ

皆様から様々なご指摘をいただき、無事に書籍を出版することができました。

ありがとうございます。

Railsレシピブック 183の技

Railsレシピブック 183の技

このエントリの内容には、古いものや技術的な誤りが含まれている

可能性があります。説明やサンプルコードを見直したレシピがこの

「Ralsレシピブック」に載っていますので、ぜひご覧ください。

RMagickで画像を扱う

Webアプリケーションで必要となることの多い機能として画像のハンドリングが上げられます。本レシピでは、Rubyでよく利用される画像ライブラリであるRMagickを使って、画像のフォーマットを判別する方法と画像サイズを変更する方法、画像フォーマットの変換方法を紹介します。

RMagickとは

RMagickは高機能な画像処理ライブラリ/コマンド集であるImageMagickRubyから利用するためのライブラリです。ImageMagickでは画像の変換や特殊効果の適用をはじめ、画像に対して様々な処理を行うことができます。RMagickを使うと、Rubyスクリプト内からこのImageMagickを利用することができ、様々な画像処理をアプリケーションに組み込むことができます。詳細は下記のサイトを参照してください(英語)。

http://www.imagemagick.org/script/index.php

http://rubyforge.org/projects/rmagick

RMagickのインストール

RMagickをインストールするには、もととなるImageMagickをインストールし、それに利用してRMagickをコンパイルする、といった方法が一般的です。また、Windows環境ではコンパイル済みのバイナリも用意されています。

Windowsdeでバイナリパッケージをインストールする
  1. http://rubyforge.org/projects/rmagick より、rmagick-win32をダウンロードし、zipファイルを展開する
  2. ImageMagick-6.x.y-z-windows-dll.exeをダブルクリックし、ImageMagickのライブラリをインストールする(x.y.-zはバージョン番号)
  3. gemコマンドを利用して、zipアーカイブに含まれるRMagick-win32-1.x.y-mswin32.gemをインストールする(x.y.はバージョン番号)
 > gem install RMagick-win32-1.15.9-mswin32.gem
その他のシステムでインストールする

Mac OS XLinuxではaptやMacPortsといったパッケージ管理システムでImageMagickをインストールし、gemコマンドを利用してRMagickをインストールするのが簡単でしょう。例えばMac OS Xの場合は次のようになります。

  1. sudo port install imagemagick +darwin_8 +gs +mpeg +no_x11 +wmf
  2. sudo gem install rmagick

Mac OS Xの場合、事前にDevlopperToolsをインストールしておくことと、MacPortsでのインストール時に+gsを指定する必要があります。その他のOSでもほぼ同様の手順でインストールできるでしょう。

RMagickで画像を処理する

RMagickで画像を扱うには、まずプログラム内でgem 'rmagick'を宣言した後、画像を読み込んで各種操作を行います。画像を読み込むにはMagick::Image.from_blob(content)メソッドを利用します。

Magick::Image.from_blob()メソッドは、引数としてバイナリ文字列を受け取り、Magick::Imageインスタンスの配列を返します*1。通常はshift()して先頭の要素を取得すればよいでしょう。

require 'rubygems'
require 'RMagick' # RMagickのライブラリを読み込む。大文字小文字に注意

content = File.read("/path/to/picture.jpg")

img = Magick::Image.from_blob(content).shift

実際のRailsアプリケーションでは、アップロードされたデータを読み込んだりDBから取得したblobカラムを読み込むことが多いでしょう。

# <input name='image' type='file' />でアップロードされたデータを読み込む
img = Magick::Image.from_blob(params[:image]).shift
# entriesテーブルのimageカラムに格納されたデータを読み込む
entry = Entry.find(params[:id])
img = Magick::Image.from_blob(entry.image).shift

実際の画像への操作はこのMagick::Imageオブジェクトに対して行います。

画像のフォーマットを判別する

画像のフォーマットを判別するにはMagick::Image#format()メソッドを呼び出します。format()メソッドはそのが像のファイルタイプを文字列で返します。

img = Magick::Image.from_blob( File.read("/path/to/photo.jpg") ).shift
img.format => "JPEG"

img2 = Magick::Image.from_blob( File.read("/path/to/picture.png") ).shift
img2.format => "PNG"

画像ファイルでないものを読み込んだ場合、Magick::ImageMagickErrorやRuntimeErrorといった例外が発生します。これを利用してアップロードされたファイルが本当に画像であるかどうかを判別することもできます。

class Entry < ActiveRecord::Base
  def validates
    begin
      image = Magick::Image.from_blob(self.content)

      unelss %w(JPEG GIF PNG).member?(image)
        self.errors.add(:image, "format should be JPEG, GIF or PNG.")
      end
    rescue Magick::ImageMagickError, RuntimeError => ex
      self.errors.add(:image, "should be an image file.")
    end
  end
end

この例では、内容を画像として読み込む際に例外が発生すると、その内容が画像でないと判断し、エラーメッセージを追加しています。さらに画像が読み込めた場合にはそのフォーマットをチェックし、JPEG, GIF, PNGのどれかでない場合にも別のエラーを追加しています。

画像サイズを取得する

画像の縦横サイズを取得するには、それぞれMagick::Image#rows()、Magick::Image#columns()メソッドを呼び出します。

# 画像の高さを取得する
img.rows

# 画像の幅を取得する
img.columns
画像サイズを変更する

画像サイズを変更するには、Magick::Image#resize(new_width, new_height, filter=LanczosFilter, support=1.0)メソッドを指定します。第一引数にリサイズ後の幅、第二引数に高さを指定します。第三引数以降ではサイズ変更アルゴリズムを指定できますが、通常は省略できます。

img = Magick::Image.from_blob( File.read("/path/to/photo.jpg") ).shift

# 横400px, 縦600pxの画像オブジェクトを取得する
new_img = img.resize(400, 600) 

# resize()は新しいMagick::Imageオブジェクトを返す。
# 当然そのオブジェクトはto_blobなどで書き出せる
File.open("new_400x600.jpg","wb"){|f| f << new_img.to_blob }

また、第一引数のみを指定すると倍率を指定してサイズ変更することができます。

# 元の画像の80%にリサイズする
new_img = img.resize(0.8) 
処理した画像を書き出す、画像のフォーマットを変換する

読み込んだ画像に対し、Image::Magick.to_blobメソッドを呼び出すと、そのデータをバイナリ文字列として取得できます。この時、事前にフォーマットを指定すると画像フォーマットを変換することができます。

img = Magick::Image.from_blob( File.read("/path/to/photo.jpg") ).shift
img.format() => "JPEG"

# JPEG画像をPNGに変換する
img.format = "PNG"

# 元データをPNGに変換し、"foo.png"に書き出す
File.open("foo.png","wb"){|f| f << img.to_blob }

指定できるフォーマットには"JPEG"や"PNG"、"GIF"などがあります。詳細はMagick.formatsで定義されています。

Railsアプリケーションから使用する場合はto_blob()メソッドで得るバイナリ文字列をコントローラのsend_data()メソッドで送出する、といった使い方が多くなるでしょう。

クラス

  • Magick::Image

関連項目

*1:アニメーションGIFなど、複数の画像が一ファイルに格納されている場合を考慮しているためです

TrixTrix2011/09/20 09:43None can doubt the veartciy of this article.

xzsctkxzsctk2011/09/20 21:46UYM59I <a href="http://kzbconioyqhn.com/">kzbconioyqhn</a>

tvgfbhmuwotvgfbhmuwo2011/09/21 03:07VL1UT0 , [url=http://lgqrsypveovr.com/]lgqrsypveovr[/url], [link=http://xytszcekijcw.com/]xytszcekijcw[/link], http://gtfwejixhujr.com/

ccqoioiccqoioi2011/09/25 00:1973bkBX <a href="http://iblqhavdqnxc.com/">iblqhavdqnxc</a>

bpffqyyevsibpffqyyevsi2011/10/03 22:15HxsJZx , [url=http://fmkiwkjqegqz.com/]fmkiwkjqegqz[/url], [link=http://naqcncnrhcly.com/]naqcncnrhcly[/link], http://kioouzhmnzta.com/

PreethiPreethi2012/08/31 18:06Sharp tihkning! Thanks for the answer.

wnwwgixcwnwwgixc2012/09/01 06:53zNSK8s <a href="http://ozxashjcqown.com/">ozxashjcqown</a>

lsgiikmlsgiikm2012/09/01 17:08oqQBlt , [url=http://xzbfrdrwnbwa.com/]xzbfrdrwnbwa[/url], [link=http://krdhqazifmnt.com/]krdhqazifmnt[/link], http://jiygmieienoo.com/

tlmdcgbfegtlmdcgbfeg2012/09/02 20:01PCDwrX <a href="http://hxjwobkrybeb.com/">hxjwobkrybeb</a>

qnrpxepqnrpxep2012/09/04 16:41eCABYt , [url=http://wvxtrhjyyibz.com/]wvxtrhjyyibz[/url], [link=http://comrfvbzqqnk.com/]comrfvbzqqnk[/link], http://orkhywedqora.com/