rcairoの背景ぼかしにRMagickを使う 2

部品を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