rcairoの背景ぼかしにconvertを使う。

読み込んだ画像のアルファチャンネルを何とかできないものかなと、
からかってみた。
SDL::Surface#set_alpha(SDL::SRCALPHA,alpha)
を使うしか方法がないのか。
そうすると、SDL::Surfaceから Cairo::ImageSurfaceに持って行き方がわからない。
Cairoで1枚の画像を作って全面表示するのではなく、
SDL::Screen#putを使ってCairoで作った画像を部品にして、配置するしかないのか?
また、振り出しに戻ちゃった。
convert のコマンドでアルファチャンネルを変える方法をを調べたけど、わからなかった。
その時convertを使ってみたついでに、背景ぼかしをやってみた。

<後日>
Cairo::Context#paint(alpha)でアルファチャンネルを指定できた。
しょうもない迷子でした。

#!usr/bin/env ruby

require 'sdl'
require 'cairo'

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.set_source_color(:red)
cr.font_size = @font_size
@ext = cr.text_extents(@text)
x = -@ext.x_bearing
y = -@ext.y_bearing
cr.move_to(x, y)
cr.show_text(@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 Blur < Text
def initialize(w, h)
super
@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_color(:black)
cr.font_size = @font_size
@ext = cr.text_extents(@text)
x = -@ext.x_bearing
y = -@ext.y_bearing
cr.move_to(x, y)
cr.show_text(@text)
@x += 5
@y += 5
IO.popen("convert -blur 3x3 -transparent white - -","r+") do |io|
@image.write_to_png(io)
io.close_write
@image = Cairo::ImageSurface.from_png(io)
end
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 << Text.new(@w, @h)
end

def update
cr = Cairo::Context.new(@image)
@items.each do |obj|
obj.update(cr)
end
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(20)
end
end
end

SDL.init(SDL::INIT_VIDEO)
@screen = SDL::Screen.open(300, 200, SDL::Screen.info.bpp, SDL::SWSURFACE)
Phase.new(@screen).run
[PR]
by gaziya | 2011-05-22 11:36