<   2011年 05月 ( 32 )   > この月の画像一覧

cairoの文字の位置関係を見直しました。
文字のセンターは
ext = c.text_extents(text)
c.move_to((ext.x_bearing + ext.width) / -2, ext.height / 2)
で、よさそうです。
他の点も調べときました。
move_toは、絶対座標[0, 0]に部品の基準点を合わせてます。
c.matrix = Cairo::Matrix.translate(x, y)
で、任意の場所に置く。
この方法で位置関係をコントロールしてます。
マフィン変換を使いたい時は行列の乗算を使ってます。

#!usr/bin/env ruby

require 'sdl'
require 'cairo'

class BackGround
def initialize(w, h)
@w, @h = w, h
end

def update(c)
c.set_source_color(:snow)
c.rectangle(0, 0, @w, @h)
c.fill
c.set_source_color(:teal)
c.move_to(0, @h / 2)
c.line_to(@w, @h /2)
c.move_to(@w / 2, 0)
c.line_to(@w / 2, @h)
c.stroke
end
end

class Item
def initialize(w, h)
@x, @y = w / 2, h / 2
@text = 'CAIRO'
end

def update(c)
c.matrix = Cairo::Matrix.translate(@x, @y)
c.font_size = 50
ext = c.text_extents(@text)
c.set_source_color(:blue)
c.circle(0, 0, ext.x_bearing)
c.stroke
#c.circle(0, 0, -ext.y_bearing)
#c.stroke
c.set_source_color(:teal)
c.circle(0, 0, ext.width)
c.stroke
c.circle(0, 0, ext.height)
c.stroke
c.set_source_color(:green)
c.circle(0, 0, ext.x_advance)
c.stroke
#c.circle(0, 0, -ext.y_advance)
#c.stroke
#no touch
c.set_source_color(:black)
c.move_to(0, 0)
c.show_text(@text)
c.set_source_color(:blue)
#right_top
c.move_to(-ext.x_bearing, ext.height)
c.show_text(@text)
#left_top
c.move_to(-ext.x_bearing - ext.width, ext.height)
c.show_text(@text)
#right_bottom
color = Cairo::Color.parse(:green)
color.alpha = 0.6
c.set_source_color(color)
c.move_to(-ext.x_bearing, 0)
c.show_text(@text)
#left_bottom
c.move_to(-ext.x_bearing - ext.width, 0)
c.show_text(@text)
#center
color = Cairo::Color.parse(:red)
color.alpha = 0.7
c.set_source_color(color)
c.move_to((ext.x_bearing + ext.width) / -2, ext.height / 2)
c.show_text(@text)
end
end

class Phase
def initialize(w, h)
@w, @h = w, h
@screen = SDL::Screen.open(@w, @h, 32, 0)
@image = Cairo::ImageSurface.new(@w, @h)
@items = []
@items << BackGround.new(@w, @h)
@items << Item.new(@w, @h)
end

def update(c)
@items.each {|obj| obj.update(c)}
end

def run
loop do
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
c = Cairo::Context.new(@image)
self.update(c)
surface = SDL::Surface.new_from(@image.data, @w, @h, 32, @image.data.size / @h, 0, 0, 0, 0)
@screen.put(surface, 0, 0)
@screen.flip
SDL.delay(20)
end
end
end

w, h = 350, 350
SDL.init(SDL::INIT_VIDEO)
Phase.new(w, h).run
[PR]
by gaziya | 2011-05-29 12:30
wiiリモコンのモジュールを載せてなかったですね。
説明するのが、面倒だから、後回しにしてました。
前に作ったから、使い方も忘れちゃいました。
でも、せっかく作ったから、説明ないけど載せときます。
多分、テストしたと思うけど、おかしかったら直して使ってください。
以前のブログは2011年3月にあります。

#!usr/bin/env ruby

require 'ffi'

module CwiidFFI
extend FFI::Library
ffi_lib '/usr/local/lib/libcwiid.so.1.0'

# Flags
CWIID_FLAG_MESG_IFC = 0x01
CWIID_FLAG_CONTINUOUS = 0x02
CWIID_FLAG_REPEAT_BTN = 0x04
CWIID_FLAG_NONBLOCK = 0x08
CWIID_FLAG_MOTIONPLUS = 0x10

# Report Mode Flags
CWIID_RPT_STATUS = 0x01
CWIID_RPT_BTN = 0x02
CWIID_RPT_ACC = 0x04
CWIID_RPT_IR = 0x08
CWIID_RPT_NUNCHUK = 0x10
CWIID_RPT_CLASSIC = 0x20
CWIID_RPT_BALANCE = 0x40
CWIID_RPT_MOTIONPLUS = 0x80
CWIID_RPT_EXT = CWIID_RPT_NUNCHUK | CWIID_RPT_CLASSIC |
CWIID_RPT_BALANCE | CWIID_RPT_MOTIONPLUS

# LED flags
CWIID_LED1_ON = 0x01
CWIID_LED2_ON = 0x02
CWIID_LED3_ON = 0x04
CWIID_LED4_ON = 0x08

# Button flags
CWIID_BTN_2 = 0x0001
CWIID_BTN_1 = 0x0002
CWIID_BTN_B = 0x0004
CWIID_BTN_A = 0x0008
CWIID_BTN_MINUS = 0x0010
CWIID_BTN_HOME = 0x0080
CWIID_BTN_LEFT = 0x0100
CWIID_BTN_RIGHT = 0x0200
CWIID_BTN_DOWN = 0x0400
CWIID_BTN_UP = 0x0800
CWIID_BTN_PLUS = 0x1000

enum :cwiid_ext_type, [
:CWIID_EXT_NONE,
:CWIID_EXT_NUNCHUK,
:CWIID_EXT_CLASSIC,
:CWIID_EXT_BALANCE,
:CWIID_EXT_MOTIONPLUS,
:CWIID_EXT_UNKNOWN
]

enum :cwiid_error,[
:CWIID_ERROR_NONE,
:CWIID_ERROR_DISCONNECT,
:CWIID_ERROR_COMM
]
class AccCal < FFI::Struct
layout :zero, [:uint16,3],
:one, [:uint16,3]
end

class BalanceCal < FFI::Struct
layout :right_top, [:uint16,3],
:right_bottom, [:uint16,3],
:left_top, [:uint16,3],
:left_bottom, [:uint16,3]
end

class CwiidIrSrc < FFI::Struct
layout :valid, :char,
:pos, [:uint16, 2],
:size, :uint8
end

class NunchuckState < FFI::Struct
layout :stick, [:uint8, 2],
:acc, [:uint8, 3],
:buttons, :uint8
end

class ClassicState < FFI::Struct
layout :l_stick, [:uint8, 2],
:r_stick, [:uint8, 2],
:l, :uint8,
:r, :uint8,
:buttons, :uint16
end


class BalanceState < FFI::Struct
layout :right_top, :uint16,
:right_bottom, :uint16,
:left_top, :uint16,
:left_bottom, :uint16
end

class MotionplusState < FFI::Struct
layout :angle_rate, [:uint16, 3],
:low_speed, [:uint8,3]
end

class ExtState < FFI::Union
layout :nunchuck, NunchuckState,
:classic, ClassicState,
:balance, BalanceState,
:motionplus, MotionplusState
end


class CwiidState < FFI::Struct
layout :rpt_mode, :uint8,
:led, :uint8,
:rumble, :uint8,
:battery, :uint8,
:buttons, :uint16,
:acc, [:uint8, 3],
:ir_src, [CwiidIrSrc, 4,],
:ext_type, :cwiid_ext_type,
:ext, ExtState,
:error, :cwiid_error
end

attach_function :str2ba,[:string,:pointer],:int
attach_function :cwiid_open,[:pointer,:int],:pointer
attach_function :cwiid_close,[:pointer],:int
attach_function :cwiid_set_rumble,[:pointer,:int],:int
attach_function :cwiid_set_led,[:pointer,:int],:int
attach_function :cwiid_get_acc_cal,[:pointer,:cwiid_ext_type,AccCal],:int
attach_function :cwiid_get_balance_cal,[:pointer,BalanceCal],:int
attach_function :cwiid_set_rpt_mode,[:pointer,:uint8],:int
attach_function :cwiid_get_state, [:pointer, CwiidState], :int
end
[PR]
by gaziya | 2011-05-28 21:38
バグの原因わかりました。
rubyをバージョンアップすれば解決かと思ったがダメだった。
だけど色々試して、やっとわかった。
プログラムの途中に
@pixels = magick.export_pixels_to_str(0, 0, @w, @h, 'RGBA')
@image = Cairo::ImageSurface.new(@pixels, 0, @w, @h, @pixels.size / @h)
が、ある。
これを
pixels = magick.export_pixels_to_str(0, 0, @w, @h, 'RGBA')
@image = Cairo::ImageSurface.new(pixels, 0, @w, @h, pixels.size / @h)
こうすると、バグる。何故?
普段、こんなとこは気にしないからヒドいめにあったよ。
これからは、よく覚えておかないと。

ruby/sdl,rcairo,RMagickの組み合わせで、使えるようになった。
基本的に、cairoで描写、RMagickでエフェクトでやっていきます。

#!usr/bin/env ruby

require 'sdl'
require 'cairo'
require 'RMagick'

class BackGround
def initialize(w, h)
@w, @h = w, h
end

def update(c)
c.set_source_color(:white)
c.rectangle(0, 0, @w, @h)
c.fill
end
end

class Item
def initialize(w, h)
@w, @h = w, h
@x, @y = @w / 2, @h / 2
@image = Cairo::ImageSurface.new(w, h)
c = Cairo::Context.new(@image)
c.matrix = Cairo::Matrix.translate(@x, @y)
c.set_source_color(:red)
c.circle(0, 0, 60)
c.fill
magick = Magick::Image.new(@w, @h).import_pixels(0,0, @w, @h, 'RGBA', @image.data)
magick = magick.splice(@w / 2, @h / 2, 10, 10)
@pixels = magick.export_pixels_to_str(0, 0, @w, @h, 'RGBA')
@image = Cairo::ImageSurface.new(@pixels, 0, @w, @h, @pixels.size / @h)
#pixels = magick.export_pixels_to_str(0, 0, @w, @h, 'RGBA')
#@image = Cairo::ImageSurface.new(pixels, 0, @w, @h, pixels.size / @h)
end

def update(c)
c.set_source(@image)
c.paint
end
end

class Phase
def initialize(w, h)
@w, @h = w, h
@screen = SDL::Screen.open(@w, @h, 32, 0)
@image = Cairo::ImageSurface.new(@w, @h)
@items = []
@items << BackGround.new(@w, @h)
@items << Item.new(@w, @h)
end

def update(c)
@items.each {|obj| obj.update(c)}
end

def run
loop do
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
c = Cairo::Context.new(@image)
self.update(c)
surface = SDL::Surface.new_from(@image.data, @w, @h, 32, @image.data.size / @h, 0, 0, 0, 0)
@screen.put(surface, 0, 0)
@screen.flip
SDL.delay(20)
end
end
end

w, h = 200, 200
SDL.init(SDL::INIT_VIDEO)
Phase.new(w, h).run
[PR]
by gaziya | 2011-05-28 17:13
わかってみれば簡単だが、ハマってる時は全然見えない。
sudo gem1.9.1 install rubysdl
こういうことだ。
gem1.9.1とコマンドを打たなきゃならなかったのだ。
ruby1.9にすると
require "rubygems" がいらないんだね。
これで、スッキリする。
ヴァージョンアップの流れは、こうだ。

sudo apt-get install ruby1.9
sudo apt-get install libsdl-dev
sudo gem1.9.1 install rubysdl
sudo apt-get install imagemagick
sudo apt-get install libmagick9-dev
sudo gem1.9.1 install rmagick
sudo apt-get install libcairo2-dev
sudo gem1.9.1 install cairo

sudo ln -f /usr/bin/ruby1.9.1 /usr/bin/ruby
sudo ln -f /usr/bin/irb1.9.1 /usr/bin/irb
sudo ln -f /usr/bin/gem1.9.1 /usr/bin/gem
[PR]
by gaziya | 2011-05-28 14:46
RMagickのエフェクトを試すのに、画面をキャプチャーして色々試してみた。
ちょっと、面白いかな?
displayは、エスケープキーで閉じれる。
img.method(m).callのmethodは、Objectクラスのメソッドです。
こういうのを、試す時は使いかってが、いいかも。
RMagickでは、ないけど、とても参考になるページを見つけた。
http://kyle-in-jp.blogspot.com/
いけてます!

#!usr/bin/env ruby

require 'RMagick'

img = Magick::Image.capture { self.filename = "root" }
#img = Magick::Image.read("??.JPG").first
img0 = img.emboss
img0.display
[
:median_filter,
:negate,
:blur_image,
:edge,
:spread,
:charcoal
].each do |m|
img0 = img.method(m).call
img0.display
end
[PR]
by gaziya | 2011-05-27 23:49
Cairo::SurfacePattern.newを使えれば、rcairoの能力を大体マスターできたと思う。
結局、Cairo::context#set_source , set_source_colorってのは、形のテキスチャーってことだったんだね。
やっと、理解できたよ。
これからは、RMagickとconvertのマニュアルを見ながら、面白そうなのを探して試してみます。
まあ、これで一息です。フー

#!usr/bin/env ruby

require 'cairo'
require 'RMagick'

w, h = 100, 100
maru = Cairo::ImageSurface.new(w, h)
cr = Cairo::Context.new(maru)
cr.set_source_color(:blue)
cr.rectangle(0, 0,w, h)
cr.fill
cr.set_source_color(:orange)
cr.set_line_width(20)
cr.circle(w / 2, h / 2, 35)
cr.stroke
a= []
mtrx = Cairo::Matrix::translate(w / 2, h / 2)
(-45 .. 314).step(90) do |d|
r= d * Math::PI / 180
a << mtrx.transform_point(Math::cos(r) * 45 , Math::sin(r) * 45)
end
batu = Cairo::ImageSurface.new(w, h)
cr = Cairo::Context.new(batu)
cr.set_source_color(:teal)
cr.rectangle(0, 0,w, h)
cr.fill
cr.set_source_color(:orange)
cr.set_line_width(20)
cr.move_to(a[0][0], a[0][1])
cr.line_to(a[2][0], a[2][1])
cr.move_to(a[1][0], a[1][1])
cr.line_to(a[3][0], a[3][1])
cr.stroke
m_list = Magick::ImageList.new
m_list << Magick::Image.new(w, h).import_pixels(0,0, w, h, 'BGRA', maru.data)
m_list << Magick::Image.new(w, h).import_pixels(0,0, w, h, 'BGRA', batu.data)
m_list << Magick::Image.new(w, h).import_pixels(0,0, w, h, 'BGRA', batu.data)
m_list << Magick::Image.new(w, h).import_pixels(0,0, w, h, 'BGRA', maru.data)
magick = m_list.montage {self.geometry = Magick::Geometry.new(w / 4, h / 4)}
#magick.display
pixels = magick.export_pixels_to_str(0, 0, magick.columns, magick.rows, 'BGRA')
cairo = Cairo::ImageSurface.new(pixels, 0, magick.columns, magick.rows, pixels.size / magick.rows)
ptrn = Cairo::SurfacePattern.new(cairo)
ptrn.set_extend(Cairo::EXTEND_REPEAT)
w, h = 500, 500
image = Cairo::ImageSurface.new(w, h)
cr = Cairo::Context.new(image)
cr.set_source_color(:white)
cr.rectangle(0, 0,w, h)
cr.fill
cr.set_source(ptrn)
cr.set_line_width(100)
cr.circle(w / 2, h / 2, 160)
cr.stroke
Magick::Image.new(w, h).import_pixels(0,0, w, h, 'BGRA', image.data).display
[PR]
by gaziya | 2011-05-26 23:25
cairoとRMagickの描写比較をしたみた。
見た目は、そんなにかわらない。
描き方も比べてみた。
どちらの書き方いいかな?
RMagickは、なんでもできるみたいだし、どういう風に使ったものかな?
cairoで描写したほうが、マトリックス変換に有利かな?
RMagickがドロー系なら、拡大すると画像が荒くなりそうだし。
SDLの位置関係のコントロールもcairoでなれちゃったから、
RMagickは、エフェクト用で使ってみるかな?
ちょっと、試行錯誤してみます。
今回、cairoのフォントの位置関係がよくわからなくなっちゃいました。
また、考えます。

#!usr/bin/env ruby

require 'cairo'
require 'RMagick'

w, h = 200, 200
m_list = Magick::ImageList.new

text = "cairo"
cairo = Cairo::ImageSurface.new(w, h)
cr = Cairo::Context.new(cairo)
cr.set_source_color(:white)
cr.rectangle(0, 0,w, h)
cr.fill
cr.set_source_color(:orange)
cr.circle(w / 2, h / 2, 80)
cr.fill_preserve
cr.set_source_color(:blue)
cr.stroke
cr.set_source_color(:black)
cr.font_size = 70
ext = cr.text_extents(text)
x = w / 2 - ext.x_bearing - ext.width / 2
y = h / 2 + ext.height / 2
cr.move_to(x, y)
cr.show_text(text)
m_list << Magick::Image.new(w, h).import_pixels(0,0, w, h, 'BGRA', cairo.data)

text = "RMagick"
img = Magick::Image.new(w, h)
img.background_color = "white"
gc =Magick::Draw.new
gc.fill('red')
gc.stroke('blue')
gc.circle(w / 2, h / 2, 20, h / 2)
gc.draw(img)
Magick::Draw.new.annotate(img, 0, 0, 0, 0, text) do
self.gravity = Magick::CenterGravity
self.pointsize = 50
self.fill = "black"
self.stroke = "none"
end
m_list << img

cairo = Cairo::ImageSurface.new(w, h)
cr = Cairo::Context.new(cairo)
cr.set_source_color(:white)
cr.rectangle(0, 0,w, h)
cr.fill
cr.move_to(110,100)
cr.rel_line_to(0, -75)
cr.arc(110,100, 75, -90 * Math::PI / 180, 180 * Math::PI / 180)
cr.close_path
cr.set_source_color(:red)
cr.fill_preserve
cr.set_source_color(:blue)
cr.stroke
cr.move_to(97.5, 87.5)
cr.rel_line_to(0, -75)
cr.arc_negative(97.5, 87.5, 75, -90 * Math::PI / 180, 180 * Math::PI / 180)
cr.close_path
cr.set_source_color(:orange)
cr.fill_preserve
cr.set_source_color(:blue)
cr.stroke
m_list << Magick::Image.new(w, h).import_pixels(0,0, w, h, 'BGRA', cairo.data)

img =Magick::Image.new(w, h){self.background_color = "white"}
gc = Magick::Draw.new
gc.fill('red')
gc.stroke('blue')
gc.stroke_width(2)
gc.path('M110,100 h-75 a75,75 0 1,0 75,-75 z')
gc.fill('yellow')
gc.path('M97.5,87.5 v-75 a75,75 0 0,0 -75,75 z')
gc.draw(img)
m_list << img

magick = m_list.montage do
self.background_color = 'black'
self.geometry = Magick::Geometry.new(w, h, 2, 2)
end
magick.display
[PR]
by gaziya | 2011-05-26 20:32
RMagickの良いとこは、一時ファイルを作らずに複数の画像を合成できるところだと思う。
rcairoとRMagickの連係を知るためのプログラムを作った。
export_pixels_to_str で使う mapは、'BGRA' だった。
以前は、黒を使ったからmapが違っても問題なかった。
ちなみに以前の間違ったmapは直しておいた。
下のプログラムで表示されるdisplayはエスケープキーで終了する。
2回エスケープキーを押してプログラムは終了です。

#!usr/bin/env ruby

require 'cairo'
require 'RMagick'

w, h = 100, 200
img = []
[:red, :green, :blue].each do |color|
cairo = Cairo::ImageSurface.new(w, h)
Cairo::Context.new(cairo) do |cr|
cr.set_source_color(color)
cr.rectangle(0, 0,w, h)
cr.fill
end
img << cairo
end
map = 'BGRA'
m_list = Magick::ImageList.new
img.each do |cairo|
m_list << Magick::Image.new(w, h).import_pixels(0,0, w, h, map, cairo.data)
end
md = Magick::Draw.new
md.annotate(m_list[0], 0, 0, 0, 0, "RMagick") do |str|
str.gravity = Magick::CenterGravity
str.pointsize = 20
str.fill = "black"
str.stroke = "white"
end
magick = m_list.append(false)
magick.display
map = 'BGRA'
pixels = magick.export_pixels_to_str(0, 0, magick.columns, magick.rows, map)
cairo = Cairo::ImageSurface.new(pixels, 0, magick.columns, magick.rows, pixels.size / magick.rows)
cairo.write_to_png('/tmp/image')
`display /tmp/image`
[PR]
by gaziya | 2011-05-25 21:04
部品をSDL::surfaceにして試したみたが、
Cairoと比べると、汚い。
なんとか、CairoのImageSurfaceを使いたいと思い試行錯誤してみた。
RMagickで、毎回変換すると、バグらないみたい。
よくわからないけど、convertと併用で、しばらく使ってみる。
もしかして、ruby1.9では、大丈夫かもしれない?!
今回のは、セーフなパターン

#!usr/bin/env ruby

require 'sdl'
require 'cairo'
require 'RMagick'

class BackGround
def initialize(w, h)
@w, @h = w, h
end

def update(cr)
cr.set_source_color(:white)
cr.rectangle(0, 0, @w, @h)
cr.fill
end
end

class Text
def initialize(w, h)
@text = "Cairo"
@x, @y = w / 2, h / 2
@font_size = 100
image = Cairo::ImageSurface.new(w, h)
cr = Cairo::Context.new(image)
cr.font_size = @font_size
@ext = cr.text_extents(@text)
end

def update(cr)
cr.matrix = Cairo::Matrix.translate(@x, @y)
cr.set_source(@image, -@ext.width / 2, -@ext.height / 2)
cr.paint
end
end

class Body < Text
def initialize(w, h)
super
@image = Cairo::ImageSurface.new(w, h)
cr = Cairo::Context.new(@image)
cr.set_source_color(:red)
cr.font_size = @font_size
cr.move_to(-@ext.x_bearing, -@ext.y_bearing)
cr.show_text(@text)
end
end

class Blur < Text
def initialize(w, h)
super
@cairo = Cairo::ImageSurface.new(w, h)
cr = Cairo::Context.new(@cairo)
cr.set_source_color(:white)
cr.rectangle(0, 0, w, h)
cr.fill
cr.set_source_color(:black)
cr.font_size = @font_size
cr.move_to(-@ext.x_bearing + 5, -@ext.y_bearing + 5)
cr.show_text(@text)
@value = 1
end

def update(cr)
@value += 1
@value = 1 if @value > 10
magick = Magick::Image.new(@cairo.width, @cairo.height)
magick.import_pixels(0,0, @cairo.width, @cairo.height, 'BGRA', @cairo.data)
magick = magick.blur_image(radius= @value, sigma= @value)
pixels = magick.export_pixels_to_str(0, 0, magick.columns, magick.rows, 'BGRA')
@image = Cairo::ImageSurface.new(pixels, 0, magick.columns, magick.rows, pixels.size / magick.rows)
super
end
end

class Phase
def initialize(screen)
@screen = screen
@w, @h = @screen.w, @screen.h
@image = Cairo::ImageSurface.new(@w, @h)
@items = []
@items << BackGround.new(@w, @h)
@items << Blur.new(@w, @h)
@items << Body.new(@w, @h)
end

def update
cr = Cairo::Context.new(@image)
@items.each {|obj| obj.update(cr)}
surface = SDL::Surface.new_from(@image.data, @image.width, @image.height, 32, @image.stride, 0, 0, 0, 0)
@screen.put(surface, 0, 0)
end

def run
loop do
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
self.update
@screen.flip
SDL.delay(100)
end
end
end

SDL.init(SDL::INIT_VIDEO)
screen = SDL::Screen.open(300, 200, 32, 0)
Phase.new(screen).run
[PR]
by gaziya | 2011-05-24 20:23
convertも色々できるみたいだ。
もう少し、探ってみようと思いRMagickをインストールした。
sudo apt-get install librmagick-ruby

ruby/sdlで動かしたら、一瞬画面は表示したが
[BUG] Segmentation fault
ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-linux]
Aborted
が、出て落ちた。
ネットで調べたけど、わからない。
だけどcairoとRMagickの組み合わせは使える。
こんな感じだ。

#!usr/bin/env ruby

require 'cairo'
require 'RMagick'

class BackGround
def initialize(w, h)
@w, @h = w, h
end

def draw(cr)
cr.set_source_color(:white)
cr.rectangle(0, 0, @w, @h)
cr.fill
end
end

class Text
def initialize(w, h)
@text = "Cairo"
@x, @y = w / 2, h / 2
@font_size = 100
@image = Cairo::ImageSurface.new(w, h)
@cr = Cairo::Context.new(@image)
@cr.font_size = @font_size
@ext = @cr.text_extents(@text)
end

def draw(cr)
cr.matrix = Cairo::Matrix.translate(@x, @y)
cr.set_source(@image, -@ext.width / 2, -@ext.height / 2)
cr.paint
end
end

class Body < Text
def initialize(w, h)
super
@cr.set_source_color(:red)
@cr.move_to(-@ext.x_bearing, -@ext.y_bearing)
@cr.show_text(@text)
end
end

class Blur < Text
def initialize(w, h)
super
@cr.set_source_color(:white)
@cr.rectangle(0, 0, w, h)
@cr.fill
@cr.set_source_color(:black)
@cr.move_to(-@ext.x_bearing, -@ext.y_bearing)
@cr.show_text(@text)
@x += 5
@y += 5
magick = Magick::Image.new(@image.width, @image.height)
magick.import_pixels(0,0, @image.width, @image.height, 'BGRA', @image.data)
magick = magick.blur_image(radius = 3, sigma = 3)
pixels = magick.export_pixels_to_str(0, 0, magick.columns, magick.rows, 'BGRA')
@image = Cairo::ImageSurface.new(pixels, 0, magick.columns, magick.rows, pixels.size / magick.rows)
end
end

w, h = 300, 200
cairo = Cairo::ImageSurface.new(w, h)
items = []
items << BackGround.new(w, h)
items << Blur.new(w, h)
items << Body.new(w, h)
cr = Cairo::Context.new(cairo)
items.each {|obj| obj.draw(cr)}
cairo.write_to_png('/tmp/blur_image')
`display /tmp/blur_image`
[PR]
by gaziya | 2011-05-23 23:09