Rubyでも画像のリサイズ、切り抜きが自由自在(かもしれない)クラスライブラリを作ってみた
PHPでの画像のリサイズ、切り抜きが自由自在「class.image.php」を読んだら、無償に作りたくなったので脊髄反射的にやってみた。
PHPのほうはGDを使っているみたいだけど、こっちはImageMagick(RMagick)を使ってます。RMagickだとWindowsとLinuxの両方で動くので便利。クライアントPCがWindowsだからWindowsで開発して、テスト/本番はLinuxというパターンの自分の職場では重宝します。
そういえば、明日も仕事なんだけど、気がついたら既に4時過ぎという罠orz
かなりやっつけ仕事なので、突っ込みとか大歓迎(って誰も読んでないと思うけどw)
simple_image.rb
$KCODE = 'u' require 'jcode' require 'rubygems' require 'RMagick' require 'base64' # #= RMagickを利用した画像処理を簡単にできるはずのクラスライブラリ # #Author:: mingos #Version:: 1.0 2008-02-22 #License:: Rubyライセンスに準拠 # 自由に使ってやってください # #=== 使い方 #==== PNGをGIFに変換して保存 # image = SimpleImage.from_file('sample.png') # image.to_gif # image.path = 'sample.gif' # image.save # #==== リサイズ # 30x50にリサイズして、pngに変換して保存 # image.resize(30, 50) # image.to_png # image.path = 'new.png' # image.save # #==== 切り取り # (0,30)から100x120の部分を切り取る # image.crop({ # :x => 0, :y => 30, # :width => 100, :height => 120 # }) # #==== 画像の中心を切り取る # 中心から100x100の部分を切り取る # image.crop_center(100, 100) # #==== 指定した座標に画像を重ねる # (0, 50)にsample.pngを合成 # image.composite('sample.png', 0, 50) # #==== 中心に画像を重ねる # sample.pngを中心に合成 # image.composite_center('sample.png') # #=== 開発履歴 #* 1.0 2008-02-22 # * とりあえず作成してみた class SimpleImage # 保存先のパス # from_fileで生成された場合、読み込んだファイルのパスが設定される # from_blobで生成された場合は設定されないので、saveメソッドを実行する前に # pathに保存先のパスを設定しておく必要がある attr_accessor :path #=== ファイルからSimpleImageオブジェクトを生成する # #_path_ :: 画像ファイルのパス #戻り値 :: SimpleImageオブジェクト def self.from_file(path) unless File.exist?(path) raise ArgumentError, "File Not Found:'#{path}'" end image = SimpleImage.new(Magick::Image.read(path).first) image.path = path image end #=== blobからSimpleImageオブジェクトを生成する # #_blob_ :: blobデータ #戻り値 :: SimpleImageオブジェクト def self.from_blob(blob) SimpleImage.new(Magick::Image.from_blob(blob).first) end #=== 現在のフォーマットを返す # #戻り値 :: 現在の画像フォーマット(JPEG,GIF,PNG) def format @image.format end #=== 画像の幅 # #戻り値 :: 画像の幅 def width @image.columns end #=== 画像の高さ # #戻り値 :: 画像の高さ def height @image.rows end #=== 画像データ(blog)を返す # #戻り値 :: 画像データ(blob) def content @image.to_blob end #=== PNGに変換する def to_png unless @image.format == "PNG" @image.format = 'PNG' end end #=== JPEGに変換する # to_jpegと同じ def to_jpg to_jpeg end #=== JPEGに変換する def to_jpeg unless @image.format == "JPEG" @image.format = "JPEG" end end #=== GIFに変換する def to_gif unless @image.format == "GIF" @image.format = "GIF" end end #=== 指定したサイズに変更する # #_width_ :: 変更後の幅 #_height_ :: 変更後の高さ def resize(width, height) @image = @image.resize(width, height) end #=== 任意の座標から指定したサイズに切り抜く # 使用例: (0,30)の位置から100x50の画像を切り抜く # image = SimpleImage.from_file('sample.jpg') # image.crop({:x => 0, :y => 30, :width => 100, :height => 50}) # #_opts_ :: オプション def crop(opts = {}) opts = { :x => 0, :y => 0, :width => self.width, :height => self.height }.update opts @image = @image.crop(opts[:x], opts[:y], opts[:width], opts[:height], true) end #=== ファイルに保存する # pathメソッドで指定したパスに保存される # # 例1: この場合はsample.pngが保存先として設定される # image = SimpleImage.from_file('sample.png') # image.save # # 例2: pathメソッドで保存先をnew.pngに変更(別名保存)する # image = SimpleImage.from_file('sample.png') # image.path = 'new.png' # image.save # # 例3: from_blobで生成した場合、pathを実行しないと保存先が設定されないため保存に失敗する # image = SimpleImage.from_blog(blob) # image.save これは失敗する # image.path = './sample.png' 保存先を指定する # image.save これは成功する # #戻り値 :: 保存に成功した場合true、失敗時false def save unless @path return false end begin File.open(@path, 'w'){|f| f.binmode f.print @image.to_blob } return true rescue end return false end #=== 画像を中心から指定したサイズに切り抜く # 例: 画像の中心から50x100の画像を切り抜く # image = SimpleImage.from_file('sample.gif') # image.crop_center(50, 100) # #_width_ :: 幅 #_height_ :: 高さ def crop_center(width, height) @image = @image.crop(Magick::CenterGravity, width, height, true) end #=== 指定のフォーマットに変換する # PNG, JPEG, GIFへ変換するメソッド(to_png, to_jpeg, to_gif)を内部で呼んでいるだけ # #_format_ :: 変換先のフォーマット。PNG,JPEG,GIFのいずれかを指定する def change_format(format) format = format.to_s.upcase if format == 'JPG' format = 'JPEG' end format = format.gsub(/jpeg/, 'jpg') case format when 'JPEG' self.to_jpeg when 'GIF' self.to_gif when 'PNG' self.to_png end end #=== 指定したファイルを画像の任意の座標に合成する # 例: base.pngの(30, 50)にsample.pngを重ねる # image = SimpleImage.from_file('base.png') # image.composite('sample.png', 30, 50) # #_path_ :: 合成する画像ファイルのパス #_x_ :: 配置するx座標 #_y_ :: 配置するy座標 def composite(path, x, y) begin src = Magick::Image.read(path).first # srcと自身のフォーマットを合わせる change_format(src.format) @image = @image.composite(src, x, y, Magick::OverCompositeOp) rescue Exception => e puts e.message end end #== 指定したファイル画像の中心に合成する # 例: base.pngの中心にsample.pngを重ねる # image = SimpleImage.from_file('base.png') # image.composite_center('sample.png') # #_path_ :: 合成する画像ファイルのパス def composite_center(path) begin src = Magick::Image.read(path).first # srcと自身のフォーマットを合わせる change_format(src.format) @image = @image.composite(src, Magick::CenterGravity, Magick::OverCompositeOp) rescue Exception => e puts e.message end end private def initialize(image) @image = image end end