画像ファイルはものすごい数のピクセルデータの集まりだ。手でひとつずつ打ち込むなんてとても無理。
コンピュータのパワーを使って大量のデータを一気に書き出させる:そのためのプログラムを作って 仕事をさせる。
最初に走らせたプログラムを見てみよう
# ex-001.rb
nx = 600 # 横のサイズを設定
ny = 480 # 縦のサイズを設定
puts "P6" # ファイルの種類を指定
puts "# Let's try Graphics with Ruby" # コメント(なんでもいい)を出力
puts "#{nx} #{ny}" # 600 480 が出力される
puts "255" # 255 が最も明るいという指定
for i in 0 .. ny - 1 ## これ以降が実際にピクセルを出力する部分
for j in 0 .. nx - 1
r = 255 #
g = 0 # RGB に 255, 0 255 を与えている→マゼンタの色を指定
b = 255 #
print r.chr + g.chr + b.chr # 3色からなるピクセルを出力
end
end
上のソースには for で始まる行がある。これはその後にある end と対になって,for ループという仕掛けを 実現する。たとえば次のプログラムは, 3,6,9,12,18 と出力して行く。つまり i という変数が 1,2,3,4,5,6 と変化しながら繰り返し実行される。
for i in 1 to 6 puts i * 3 end
このプログラムでは,2つのループが組み合わされている。
for i in 0 .. ny - 1
for j in 0 .. nx - 1
.....
.....
end
end
これは,ピクセルの配置が横と縦の2次元になっているために,横にピクセルを並べるための繰り返しを, 縦に並べる繰り返しの中に入れなければならないからだ。次の図にそのことを示した。
一面同じ色の画像なんてほとんど使いものにはならない。 画面全体を4分割して色分けした例を紹介しよう。
# ex-002.rb
nx = 600
ny = 480
puts "P6"
puts "# Love Kyojo!"
puts "#{nx} #{ny}"
puts 255
for i in 0 .. ny - 1
for j in 0 .. nx - 1
if i < ny / 2 then # i が ny の半分より小さかったら
b = 127 # b を 127 にする
else # そうでなかったら
b = 255 # b を 255 にする
end
if j < nx / 2 then # j が nx の半分より小さかったら
r = 255 # r を 255 にする
else # そうでなかったら
r = 0 # r を 0 にする
end
g = 0 # g は常に 0 のまま
print r.chr + g.chr + b.chr
end
end
作られる画像は次のようになる(説明の文字が後から書き込まれている)。 これはプログラムの中の if の働きによるものだ。プログラムのコメントと 画像を見比べると,この絵が作られる理屈がわかる。
グラデーション(グラジェントともいう) は色の濃さが滑らかに移り変わるようなパターンだ。次のサンプルプログラムを 走らせてみよう。
# ex-003.rb
nx = 600
ny = 480
puts "P6"
puts "# Gradation "
puts "#{nx} #{ny}"
puts 255
for i in 0 .. ny - 1
for j in 0 .. nx - 1
r = j % 200
g = i % 240
b = 0
print r.chr + g.chr + b.chr
end
end
プログラムの中にある j % 200 というのは, j を 200 で割った余りを計算するものだ。 for ループの中で j は 0, 1, 2, ... と増えていき ..., 200, 201 と 200 を超えた ところで(余りだから) 0, 1, ... とまた戻る。結局, 横に 1 ピクセル進むごとに 赤みを増して 200 進むとまた 0 に戻ることになる。 i についても同様で,下に向かって 緑のグラデーションがかかる。
# ex-004.rb
nx = 600
ny = 480
puts "P6"
puts "# Let's try Graphics with Ruby"
puts "#{nx} #{ny}"
puts "255"
for i in 0 .. ny - 1
for j in 0 .. nx - 1
r = (i * j / 100) % 250
g = 0
b = 0
print r.chr + g.chr + b.chr
end
end
このプログラムは,i と j の積を100で割った値(こうすることであまりにも大きくなりすぎないようにしている)を計算し,それが 250 を超えないように 余りをとって r の値にしている。