Top / ruby / rmagick

ruby/rmagick

このエントリーをはてなブックマークに追加 Delicious Check
更新: 2011-10-17 (月) 06:30:42 (1015d)

リンク

RMagickとは?

画像処理ソフトウェア ImageMagick と Ruby を繋ぐ夢の架け橋。
ImageMagickは高機能だけど重い、と評判悪し。
サムネ作るとかの簡単な処理だけなら、Imlib2-Ruby (Imlib2 と Ruby のバインダ)使え、という話みたい。
でも、 Imlib2 はフィルタ少ない。
web サイトのシステム内で使うなら、 Imlib2。そうじゃないなら、 RMagick という使い分けが良さげ。

インストール

RubyForge ダウンロードページから取ってくる。
Windows 版は、同梱されている ImageMagic をインスコしないと上手く動かないので注意。

cd "展開したパス"
gem install "rmagick-2.12.0-x86-mswin32.gem"

RMagick2.so のload errorが出たら、PATHを確認。 PATH通っているのにまだエラー出たら以下の手順をちゃんと踏んでいるか確認。

  1. アーカイブを落としてくる。
  2. 同梱のImageMagickをインストール
  3. 同梱のRMagickをインストール
  4. マシンの再起動(忘れがち)

インストール2

概念

  • Image - 1枚の画像を表す。
  • ImageList - 画像のリスト。複数枚をまとめてアニメにしたりする。1枚を扱うときはImageと大体同じ。Arrayのサブクラス。
  • Draw - 文字を描いたりする。

最初に

動作確認

require "rubygems"
require "RMagick"
include Magick

img = Magick::Image.new(100,100){self.background_color = "red"}
img.write('どこぞのパス/a.png')

赤い■の a.png が出来てたらOK

全ピクセルのループ

require "rubygems"
require "RMagick"
include Magick

img1 = Magick::Image.new(100,100){self.background_color = "red"}

img1.each_pixel {|pixel,x,y|
  print '[' + x.to_s + ',' +  y.to_s + ']'
  print pixel.to_color
  print "\n"
}
 

画像作成

透過ストライプ

require "rubygems"
require "RMagick"
include Magick

n=4 #ストライプの太さ(px)
color='white' #blackにすると暗いストライプに。
opacity=0.1 #透明度 0-1 数字を1に近づけるとストライプが濃くなります。

imgl = Magick::ImageList.new
imgl.new_image(n*2,n*2){self.background_color = 'none'}

gc = Magick::Draw.new

# 右上の台形
gc.fill(color)
gc.fill_opacity(opacity)
gc.polygon(0,0, n-1,0, 2*n-1,n, 2*n-1,2*n-1)

# 左下の三角
gc.polygon(0,n+1, n-2,2*n-1, 0,2*n-1)


gc.draw(imgl)
imgl.write('出力するパス/stripe.png')

 

白ストライプ(見にくいです)

白ストライプ
白ストライプ(太さ6:半透明度0.3)

黒ストライプ

黒ストライプ
黒ストライプ(太さ6:半透明度0.3)

これらの画像をcssとかで敷き詰めて使って下さい。
面倒臭い人は、上の画像をDLして使ってOKです。

<div style="background-color:red;background-image:url(stripe.pngのURL);width:100px;height:100px;">
背景:赤<br />
ストライプ:白
</div>

n=4 opacity=0.1

背景:赤
ストライプ:白
背景:赤
ストライプ:黒
背景:緑
ストライプ:白
背景:緑
ストライプ:黒
背景:青
ストライプ:白
背景:青
ストライプ:黒
背景:灰
ストライプ:白
背景:灰
ストライプ:黒
背景:白
ストライプ:白
背景:白
ストライプ:黒
背景:黒
ストライプ:白
背景:黒
ストライプ:黒

n=6 opacity=0.3

背景:赤
ストライプ:白
背景:赤
ストライプ:黒
背景:緑
ストライプ:白
背景:緑
ストライプ:黒
背景:青
ストライプ:白
背景:青
ストライプ:黒
背景:灰
ストライプ:白
背景:灰
ストライプ:黒
背景:白
ストライプ:白
背景:白
ストライプ:黒
背景:黒
ストライプ:白
背景:黒
ストライプ:黒

背景の半分だけ色を濃く(薄く)する

半分完全透明、半分半透過の画像を作って、背景にします。

require "rubygems"
require "RMagick"
include Magick

n=28 #縦の長さ
#ストライプと同じ
color='black'
opacity=0.1
translate=false #上下逆転

imgl = Magick::ImageList.new
imgl.new_image(1,n){self.background_color = 'none'}

gc = Magick::Draw.new

gc.fill(color)
gc.fill_opacity(opacity)
unless translate
	gc.polygon(0,n/2, 0,n-1)
else
	gc.polygon(0,0, 0,n/2-1)
end


gc.draw(imgl)
imgl.write('出力するパス/half_shadow.png')

 

画像(見にくいです)

ハーフシャドー

これらの画像をcssとかで敷き詰めて使って下さい。
面倒臭い人は、上の画像をDLして使ってOKです。

<div style="background-color:red;background-image:url(half_shadow.pngのURL);height:28px;float:left;font-size:24px;">
背景:赤
</div>
背景:赤
背景:緑
背景:青
背景:灰
背景:白

画像処理

元画像の用意

エクスカリバーを持っている赤兎さんを用意して読み込んでおきます。

処理前画像
require "rubygems"
require "RMagick"
include Magick

make_path = '画像のパス/'
file_name = make_path+'before.jpg'
readed_img=ImageList.new(file_name)

白黒にする

readed_img.quantize(256, Magick::GRAYColorspace).write(make_path+'after_mono.jpg')
白黒処理画像

ぼかす

readed_img.blur_image(0,2).write(make_path+'after_blur.jpg')#blur_imageの引数でぼかし具合の調整をする
ぼかし処理画像

二値化

readed_img.threshold(50).write(make_path+'after_threshold50.jpg')#引数で閾値の調整
readed_img.threshold(100).write(make_path+'after_threshold100.jpg')
readed_img.threshold(150).write(make_path+'after_threshold150.jpg')
readed_img.threshold(200).write(make_path+'after_threshold200.jpg')
二値化閾値50画像
二値化閾値100画像
二値化閾値150画像
二値化閾値200画像

エッジ(ラプラシアンフィルタ)

readed_img.edge(0).write(make_path+'after_edge0.jpg')#引数で半径の調整
readed_img.edge(2).write(make_path+'after_edge2.jpg')
readed_img.edge(5).write(make_path+'after_edge5.jpg')
エッジ半径0画像
エッジ半径2画像
エッジ半径5画像

反転(補色で置換)

readed_img.negate().write(make_path+'after_negate_false.jpg')
反転処理画像

減色

readed_img.posterize().write(make_path+'after_posterize.jpg')
減色処理画像

鉛筆画・油絵風

readed_img.sketch().write(make_path+'after_sketch.jpg')
readed_img.oil_paint().write(make_path+'after_oil_paint.jpg')
鉛筆画処理画像
油絵処理画像

ポラロイド

readed_img1.first[:Caption] = "\nakausagi\n" + Date.today.to_s

polaroid = readed_img1.polaroid(){
  self.font_weight = Magick::NormalWeight
  self.font_style = Magick::NormalStyle
  self.gravity = Magick::CenterGravity
  self.border_color = "#f0f0f8"

}

background = Magick::Image.new(polaroid.columns, polaroid.rows)
composited_polaroid = background.composite(polaroid, Magick::CenterGravity, Magick::OverCompositeOp)

composited_polaroid.write(make_path+'after_polaroid.jpg')
ポラロイド処理画像

注意点

ループで回すとメモリをパカパカ喰って、異常終了する。

require "rubygems"
require "RMagick"
include Magick

5000.times {|t|
img = Magick::Image.new(1000,1000){self.background_color = "red"}
file_name = t.to_s + '.png'
img.write('どこぞのパス/' + file_name)
}

こんなの即死。

require "rubygems"
require "RMagick"
include Magick


def run_gc
  fDisabled = GC.enable
  GC.start
  GC.disable if fDisabled
end

5000.times {|t|
img = Magick::Image.new(1000,1000){self.background_color = "red"}
file_name = t.to_s + '.png'
img.write('どこぞのパス/' + file_name)
run_gc()
}

ループの最後でGCを呼んでやるとOK。
fork して、親で Process.wait で、時々プロセス新しくやるのもあり。

ImageMagick と対応しているメソッド一覧

Image#adaptive_blur(radius=0.0, sigma=1.0)
Image#adaptive_resize(width, height)
Image#adaptive_sharpen(radius=0.0, sigma=1.0)
Image#auto_gamma_channel([channel...])
Image#auto_level_channel([channel...])
Image#bias(value)
Image#bias('value%')
Image#black_threshold(red_channel [, green_channel [, blue_channel [, opacity_channel]]])
Image#blend(overlay, src_percent, dst_percent, x_offset=0, y_offset=0)
Image#blue_shift(factor)
Image#blur_image(radius=0.0, sigma=1.0)
Image#border(width, height, color)
Image#charcoal(radius=0.0, sigma=1.0)
Image#chop(x, y, width, height)
Image#mask(image)
Image#copy
Image#dup
Image#clut_channel(clut_image [, channel...])
Image#colorize(red, green, blue, [matte, ] fill)
Image#composite_mathematics(source_image, a, b, c, d, gravity, x, y)
Image#composite(source_image, gravity, x, y, composite_op)
Image#contrast(true)
Image#contrast(false)
Image#contrast_stretch_channel( black_point, white_point [, channel...])
Image#convolve(order, kernel)
Image#crop(x, y, width, height)
Image#cycle_colormap(amount)
Image#decipher(passphrase)
Image#ticks_per_second= ticks-per-second
Image#x_resolution=width
Image#y_resolution=height
Image#deskew(threshold=0.40, auto_crop_width)
Image#distort(method, arguments, bestfit)
Image#edge(radius=0.0)
Image#emboss(radius=0.0, sigma=1.0)
Image#encipher(passphrase)
Image#equalize_channel
Image#quantum_operator(operator, value [, channel])
Image#extent(width, height, x=0, y=0)
Image#color_floodfill(x, y, color)
Image#frame(width, height, x, y, inner_bevel_width, outer_bevel_width, color)
Image#function_channel(function, arguments)
Image#fuzz="distance%"
Image#gamma_correct(red_gamma[, green_gamma[, blue_gamma]])
Image#gaussian_blur(radius=0.0, sigma=1.0)
Image#gaussian_blur_channel( radius=0.0, sigma=1.0 [, channel...])
Image#compare_channel(ref_image, metric[, channels...]){ self.highlight_color color}
Image#implode(factor)
Image#adaptive_threshold( width, height, offset)
Image#level_channel(channel, black_point=0.0, white_point=QuantumRange, gamma=1.0)
Image#levelize_channel(black_point, white_point, gamma=1.0[, channels...])
Image#level_colors(black_color, white_color, gamma=1.0[, channels...])
Image#linear_stretch(black_point [, white_point])
Image#liquid_rescale(new_width, new_height, delta_x, rigidity)
Image#compare_channel(ref_image, metric[, channels...]){ self.lowlight_color color}
Image#map(reference, dither=false)
Image#add_composite_mask(image)
Image#median_filter(radius=1.0)
Image#modulate(brightness=1.0, saturation=1.0, hue=1.0)
Image#motion_blur(radius=0.0, sigma=1.0, angle=0.0)
Image#negate(true)
Image#reduce_noise(radius)
Image#add_noise( type)
Image#normalize_channel
Image#opaque(color, fill)
Image#opaque_channel(color, fill, opacity, true)
Image#ordered_dither(N)
Image#oil_paint(radius=3.0)
Image#posterize(levels=4, dither=false)
Image#preview(type)
Image#add_profile(filename)
Image#delete_profile(name)
Image#quantize(number_colors=256, colorspace=RGBColorspace, dither=true, tree_depth=0, measure_error=false)
Image#radial_blur(angle)
Image#raise(width, height, true)
Image#raise(width, height, false)
Image#random_threshold_channel(" lowxhigh" [, channel...])
Image#recolor(matrix)
Image#remap(remap_image, dither=RiemersmaDitherMethod)
Image#resample(horizontal, vertical)
Image#resize(width, height)
Image#roll(x, y)
Image#rotate(degrees [, qualifier])
Image#sample(width, height)
Image#scale(width, height)
Image#segment(colorspace= RGBColorspace, cluster_threshold=1.0, smoothing_threshold=1.5, verbose=false)
Image#selective_blur(radius, sigma, threshold [, channel...])
Image#separate(channel...])
Image#sepiatone(threshold=QuantumRange)
Image#shade(shading=false, azimuth=30, elevation=30)
Image#shadow(x=4, y=4, sigma=4.0, opacity=4.0)
Image#sharpen(radius=0.0, sigma=1.0)
Image#shave(width, height)
Image#shear(x_degrees, y_degrees)
Image#sigmoidal_contrast_channel( contrast=3.0, mid_point=50.0, sharpen=false [, channel...])
Image#sketch(radius=0.0, sigma=1.0, angle=0.0)
Image#solarize(threshold=50)
Image#sparse_color(method, x, y, color[, x, y, color...][, channel...])
Image#splice(x, y, width, height [, color])
Image#spread(amount=3)
Image#stegano(watermark, offset)
Image#stereo(offset_image)
Image#swirl(degrees)
Image#bilevel_channel(value [, channel...])
Image#thumbnail(width, height)
Image#affine_transform( matrix)
Image#transparent(color, opacity=TransparentOpacity)
Image#paint_transparent(color, opacity, true)
Image#unsharp_mask(radius=0.0, sigma=1.0, amount=1.0, threshold=0.05)
Image#vignette(x, y, radius=0.0, sigma=10.0)
Image#wave(amplitude=25.0, wavelength=150.0)
Image#white_threshold(red_channel [, green_channel[, blue_channel[, opacity_channel]]])
Image#write(filename)
Image#blend(overlay, src_percent, dst_percent, x_offset=0, y_offset=0)
Image#displace(displacement_map, x_amplitude, y_amplitude, x_offset=0, y_offset=0)
Image#dissolve(overlay, src_percent, dst_percent, x_offset=0,y_offset=0)
Image#composite_tiled(src, composite_op=OverCompositeOp)
Image#watermark(mark, lightness=1.0, saturation=1.0, x_offset=0, y_offset=0)


ImageList#append(true)
ImageList#append(false)
ImageList#average
ImageList#coalesce
ImageList#deconstruct
ImageList#delete_at(index)
ImageList#flatten_images
ImageList#fx(expression)
ImageList#insert(index)
ImageList#[index]
ImageList#optimize_layers(method)
ImageList#composite_layers(imagelist, operator=OverCompositeOp)
ImageList#iterations=iterations
ImageList#map(reference, dither=false)
ImageList#morph(frames)
ImageList#mosaic
ImageList#quantize(number_colors=256, colorspace=RGBColorspace, dither=true, tree_depth=0, measure_error=false)
ImageList#remap()
ImageList#reverse
ImageList#scene= value
ImageList#[]=
ImageList#quantize
ImageList#write(filename)


Draw#affine(sx, rx, ry, sy, tx, ty)
Draw#affine=matrix
Draw#annotate(image, width, height, x, y, text)
Draw#stroke_antialias(true)
Draw#text_antialias(true)
Draw#text_antialias=true
Draw#draw
Draw#encoding(type)
Draw#encoding=type
Draw#font_family(font_family)
Draw#font_family=font_family
Draw#fill(color)
Draw#fill=color
Draw#font(name)
Draw#font=name
Draw#gravity(type)
Draw#gravity= type
Draw#interline_spacing(value)
Draw#interline_spacing=value
Draw#interword_spacing(value)
Draw#interword_spacing=value
Draw#kerning(value)
Draw#kerning=value
Draw#stroke_width(width)
Draw#stroke_width=width
Draw#font_stretch(font_stretch)
Draw#font_stretch=font_stretch
Draw#stroke(color)
Draw#stroke=color
Draw#stroke_width(value)
Draw#stroke_width=value
Draw#font_style(font_style)
Draw#font_style=font_style
Draw#tile(image)
Draw#text_undercolor(color)
Draw#undercolor=color
Draw#font_weight(type)
Draw#font_weight=type


Montage#background_color=color
Montage#border_color=color
Montage#border_width=value
Montage#compose=operator
Montage#fill=color
Montage#frame="geometry"
Montage#geometry="geometry"
Montage#gravity=type
Montage#matte_color=color
Montage#pointsize=value
Montage#shadow=true
Montage#stroke=color
Montage#texture=image
Montage#tile=geometry
Montage#title=string

window用help(.chm)

RMagick2.chmが無かったので作ってみた。


Top / ruby / rmagick

添付ファイル: filekakou_temp.png 237件 [詳細] filehalf_shadow.png 417件 [詳細] fileblack_6_03_stripe.png 440件 [詳細] filewhite_6_03_stripe.png 211件 [詳細] filewhite_4_stripe.png 407件 [詳細] fileblack_4_stripe.png 439件 [詳細] fileafter_polaroid.jpg 455件 [詳細] fileafter_posterize.jpg 420件 [詳細] fileafter_oil_paint.jpg 414件 [詳細] fileafter_sketch.jpg 411件 [詳細] fileafter_negate_false.jpg 462件 [詳細] fileafter_edge5.jpg 459件 [詳細] fileafter_edge2.jpg 465件 [詳細] fileafter_edge0.jpg 505件 [詳細] fileafter_threshold200.jpg 392件 [詳細] fileafter_threshold150.jpg 412件 [詳細] fileafter_threshold100.jpg 401件 [詳細] fileafter_threshold50.jpg 396件 [詳細] fileafter_blur.jpg 516件 [詳細] fileafter_mono.jpg 450件 [詳細] filebefore.jpg 385件 [詳細]