RMagick을 사용하여 GIF 생성

시각화하고 싶습니다.



라이프게임
이것을 애니메이션하기 위해 터미널을 사용하고,
그것을 ttyrec로 녹화. ttygif로 gif를 생성했지만,
이마이치 어쨌든.
비주얼라이즈에 한정하면 적당한 plot을 사용하면 좋겠지만,
gif도 갖고 싶다. ttygif의 내용은 ImageMagick이기 때문에,
직접 사용해 버리자.

RMagick



ImageMagick의 루비 바인딩

추가 new_image를 사용합시다.



직접 tempfile 사용보다 간결합니다.
new_image 해 가는 것만으로 GIF의 원프레임 추가할 수 있습니다.
def make_gif(name = "", x = 0, y = 0, fps = 0, &d)
  m = Magick::ImageList.new
  (0..fps).each { |n|
    m.new_image(x,y)
    d.call(m,n)
  }

  m.write(name)
end

make_gif



임시 파일에 한 프레임씩 내보내고,
마지막으로 그들을 하나의 GIF로 결합한다.
비효율적인 냄새.

rmagick_make_gif
require "RMagick"
require "tempfile"

def make_gif(name = "", x = 0, y = 0, fps = 0, &d)
  tfs = (0..fps).map { |n|
    mi = Magick::Image.new(x,y)

    d.call(mi,n)
    tf = Tempfile.new(["draw_gif",".gif"])
    mi.write(tf.path)
    tf
  }

  Magick::ImageList.new(*tfs.map(&:path)).tap { |mil|
    mil.iterations = 10
    mil.write(name)
    tfs.each(&:close)
  }
end

lifegame.rb


require "./lifegame.rb"
require "./rmagick_make_gif.rb"

lg = Lifegame.new(300,300)
lg.random { (rand(2) + rand(2) + rand(2)) / 3 }

make_gif("lifegame.gif",300,300,100) { |m,n|
  lg.cells.each_with_index { |cy,iy|
    cy.each_with_index { |cx,ix|
      m.pixel_color(ix,iy,"black") if cx == 1
    }
  }
  lg.apply
}





1차원 셀 오토마톤 역시.
규칙 90입니다.
require "./cells.rb"
require "./rmagick_make_gif.rb"

cs = Cells.new
bs = []
make_gif("cells.gif", 200,100,100) { |m,n|
  y = 0
  bs.push(cs.dup)
  bs.each { |cy|
    x = 0
    cy.cells.each { |cx|
      m.pixel_color(x,y,"black") if cx == 1
      x += 1
    }
    y += 1
  }
  cs.apply 90
}





터미널의 텍스트 표현의 볼륨과는 자릿수 차이에 많이 출력할 수 있으므로,
이 예제의 경우 여기를 사용하는 것이 좋습니다.

좋은 웹페이지 즐겨찾기