Ruby で OpenGL のウィンドウ・キャプチャをしようと苦労していたのですが、すばらしいライブラリを発見して成功しました。ウィンドウを BMP ファイルに落とします。Ruby で OpenGL を使うことについては、ここが参考になれば幸いです。
RubyでBMPファイルをあつかう: 脈絡なんか気にしない
リンク先のブログ記事で助かりました。コードはこちら。必要な部分を流用させてもらいました(感謝!)。まずはそれから。
class BitMap def initialize(width, height, dpi = 96) @width = width @height = height @line_size = width * 3 + (4 - (width * 3) % 4) % 4 @buf_size = @line_size * height @buf = ("\000" * @buf_size).encode('BINARY') @bit_count = 24 @compression = 0 # 圧縮無し @size_image = 0 @x_pix_per_meter = (39.375 * dpi).round @y_pix_per_meter = (39.375 * dpi).round @clr_used = 0 @cir_important = 0 end attr_accessor :buf attr_reader :width, :height # BMPファイルを出力する def write(filename) file_size = 14 + 40 + @buf_size data_offset = 14 + 40 open(filename, "wb") do |f| f.print 'BM' f.print [file_size, 0, data_offset].pack("l*") f.print [40, @width, @height].pack("l*") f.print [1, @bit_count].pack("S*") f.print [@compression, @size_image, @x_pix_per_meter, @y_pix_per_meter, @clr_used, @cir_important].pack("l*") f.print @buf end end end
そして画面キャプチャをするメソッドです。今回作ったのはこれです。引数はファイル名です。
class BitMap def self.gl_capture(fname) x = glutGet(GLUT_WINDOW_WIDTH) y = glutGet(GLUT_WINDOW_HEIGHT) bitmap = BitMap.new(x, y) glPixelStorei(GL_PACK_ALIGNMENT, 1) imgdata = glReadPixels(0, 0, x, y, GL_BGR, GL_UNSIGNED_BYTE).unpack("H*")[0] data = "" y.times do |j| (x * 3).times {|i| data += imgdata[6 * x * j + i * 2, 2].to_i(16).chr} data += "\x00" * ((4 - 3 * x % 4) % 4) end bitmap.buf = data bitmap.write(fname) end end
この記事が役に立ちました。
サンプルです。上の二つのコードを組み込んで実行して下さい。
require 'bundler/setup' require 'opengl' require 'glut' include Gl, Glut Width = Height = 200 def init glClearColor(0, 0, 255, 1) end display = proc do vertex = [-0.9, 0.9, 0.9, 0.9, 0, -0.9] glClear(GL_COLOR_BUFFER_BIT) glEnableClientState(GL_VERTEX_ARRAY) glVertexPointer(2, GL_FLOAT, 0, vertex) glLineWidth(3) glColor3f(0, 1, 0) glDrawArrays(GL_LINE_LOOP, 0, 3) BitMap.gl_capture("sample.bmp") #画像の取り込み glFlush end glutInit glutInitWindowSize(Width, Height) glutInitWindowPosition(200, 100) glutCreateWindow("Triangle") glutDisplayFunc(display) init glutMainLoop
キャプチャした画像です。