Ruby で CGI > 出力方法 > 問題
アクセス回数を、数字画像を連結された一つの画像として表示させる CGI を作成してください。 テキストで表示させるカウンターを少し変えるだけです。
♪
convert -vと入力すると、ImageMagick のバージョンが表示されるはずです。 もしこれで、「command not found」の表示が出るようでしたら、サーバー管理者にお問い合わせください。 ImageMagick がインストールされていないか、または、コマンドが convert ではなくて convert の前にいろいろくっつくのかもしれません。 なお、北大の教育用サーバーには、入っています。 (大変ポピュラーなソフトなので、たいていのサーバーには入っていますが…)
convert +append a.gif b.gif c.gifです。a.gif b.gif 以外にも並べることで、同時に多数の画像を連結することもできます。
`convert +append a.gif b.gif c.gif`なお、ヒアドキュメント等の場合と同様に #{ } で値を代入することができます。
outfile = "c.gif" `convert +append a.gif b.gif #{ outfile }`
system( "convert", "+append", "a.gif", "b.gif", "c.gif" )とします。 ⇒ system
a = [ "convert", "+append", "a.gif", "b.gif", "c.gif" ] system( *a )は上記の内容と同じになります。
system( "ls" )
filelist = STDOUT
のようにすれば、出力を変数 filelist に写し取ることができます。標準出力に勝手に出力されたくない場合は、「`」を使います。
filelist = `ls`のようにすれば、出力を変数 filelist に写し取ることができます。
puts system("sleep","3") # 3秒間だけ休止 => true puts system("hogehoge" ) # 存在しないコマンド => falseしかし、ruby 1.9 からは、コマンドが失敗したときには例外の発生(つまり、エラーとして止められる)となるそうなので、 これを回避するには、rescue で救っておくと良いでしょう。
system("sleep","3") rescue false system("hogehoge" ) rescue false
a = ["A","B"] c = ["C","D"] p a + c #=> ["A","B","C","D"] a += ["E"] p a #=> ["A","B","E"]
*
はワイルドカードです。
順番はメチャクチャかもしれないので.sort
で整えます。
Dir.glob("font/*.gif").sortの内容は、
["font/0.gif", "font/1.gif", "font/2.gif", ... , "font/9.gif" ]になります。(長くなるので、... で途中を省略しました。) ⇒ Dir.glob() , sort
♪
#!/usr/local/bin/ruby CounterIMG = "count.gif" # 出来上がり数字画像のファイル名(拡張子は .gif) CountLOG = "count.txt" # 数え上げた数字を記録したファイル Fonts = Dir.glob("font/*.*").sort # font ディレクトリの中の数字画像の配列 count = File.open(CountLOG){|f| f.read.to_i } rescue 0 # カウント数を読み込んで、文字列から整数に変換 count += 1 a = ["convert","+append"] # "-append" にすると、縦連結 for n in ("%03d" % count).split(//) do # 4桁表示にする場合は、%03d を %04d に書き直す a += [ Fonts[n.to_i] ] end a += [CounterIMG] system(*a) # 数字画像を連結します Process.waitall # 画像の連結処理が終わるのを待つ File.open(CountLOG,"w"){|f| f.print count } # カウント数を保存 print <<EOS Content-Disposition: filename="#{ ("%03d" % count) }.gif" Content-type: image/gif Content-Length: #{ File.size( CounterIMG ) } EOS f = File.open( CounterIMG ,"rb") # 画像ファイルを開く STDOUT.binmode # サーバーによっては、標準出力をバイナリーモードに変更 while line = f.gets do # データを1行づつ読み込み変数lineに写し取る print line # 画像データを出力 end f.close # 画像ファイルを閉じる
ファイルの配置。()内は、北大教育用サーバー内でのモード。
■親ディレクトリ/ ┣このCGI (755) ┣count.gif (766) ┣count.txt (766) ┗■font/ (711) ┣ 0.gif ┣ 1.gif : ┗ 9.gif
または、Location で画像ファイルに飛ばします。
#!/usr/local/bin/ruby
CounterIMG = "count.gif"
CountLOG = "count.txt"
Fonts = Dir.glob("font/*.*").sort
count = File.open(CountLOG){|f| f.read.to_i } rescue 0
count += 1
a = ["convert","+append"]
for n in ("%03d" % count).split(//) do
a += [ Fonts[n.to_i] ]
end
a += [CounterIMG]
system(*a)
Process.waitall
File.open(CountLOG,"w"){|f| f.print count }
print <<EOS
Content-type: image/gif
Content-Length: #{ File.size( CounterIMG ) }
Location: #{ CounterIMG }
EOS
以上です。