cairo と Ruby で遊んでみる

cairo は二次元画像を描くためのライブラリです。これと Ruby でちょっと GIFアニメを作って遊んでみました。

cairo は Linux ならたぶん最初から入っているようです。Linux Mint 17.2 には既に入っていたので、それを使いました。
Ruby で cairo を使うには Gem 'cairo' を使うとよいようです。Bundler で入れました。

コードはこんな感じ。

require 'cairo'
require './gifanime'

Dir.chdir("picture")

#初期設定
BD, PA, WD, BW = 20, 30, 50, 40
Window = BD * 2 + PA * 2 + WD * 4 + BW * 3

Surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, Window, Window)
C = Cairo::Context.new(Surface)

C.set_source_color(Cairo::Color.parse("#d3d3d3"))
C.rectangle(0, 0, Window, Window)
C.fill
C.set_source_color(Cairo::Color.parse("#e0ffff"))
C.rectangle(BD, BD, Window - BD * 2, Window - BD * 2)
C.fill

#小さい正方形を表すクラス
class Square
  def initialize(x, y)
    @x, @y = x, y
  end
  
  def draw
    C.set_source_rgb(rand, rand, rand)
    C.rectangle(@x, @y, WD, WD)
    C.fill
  end
end

#16個の正方形を作る
sq = 4.times.flat_map do |y|
  4.times.map do |x|
    Square.new(BD + PA + x * (BW + WD), BD + PA + y * (BW + WD))
  end
end

#最初の描画
sq.each(&:draw)

#GIFアニメ用にランダムに更新されていく画像の書き出し
100.times do |i|
  3.times { sq.sample.draw }
  Surface.write_to_png("%04d.png" % i)
end

#GIFアニメ作成
gifanime(20)

picture という名前のフォルダで作業をするので、ソースコードのあるディレクトリにフォルダを作っておいて下さい。
require './gifanime' は GIFアニメを作るためのもので、コードはここにあります。


※参考
るびま
VikiWiki - rcairo

 

自作 Gem 'oekaki' で

自作のグラフィック用 Gem 'oekaki' でほぼ同じことをやってみました。(2019/6/6)
oekaki | RubyGems.org | your community gem host
GTK+でお絵かきしてみた(Ruby) - Camera Obscura
 
oekaki_sample23.rb

require 'oekaki'

BD, PA, WD, BW = 20, 30, 50, 40
Window = BD * 2 + PA * 2 + WD * 4 + BW * 3
sq = nil

class Square
  def initialize(x, y, slot)
    @x, @y = x, y
    @slot = slot
  end
  
  def draw
    @slot.color(rand(0..0xffff), rand(0..0xffff), rand(0..0xffff))
    @slot.rectangle(true, @x, @y, WD, WD)
  end
end


Oekaki.app width: Window, height: Window do
  draw do
    lw = Window - BD * 2
    rectangle(true, 0, 0, Window, Window, color(0xf42b, 0xd202, 0x7025))
    rectangle(true, BD, BD, lw, lw, color(0xe0ff, 0xffff, 0xffff))
    
    sq = 4.times.flat_map do |y|
      4.times.map do |x|
        Square.new(BD + PA + x * (BW + WD), BD + PA + y * (BW + WD), self)
      end
    end
    
    sq.each(&:draw)
  end
  
  timer(200) do
    3.times { sq.sample.draw }
  end
end