CGIへの画像の投稿

blogサーバなど、文章だけでなく写真等のファイルを ポストできるものがある。これにはHTMLフォーム input 要素の、type="file" を利用する。

multipart/form-data

文字列や選択オプションを送信するフォームは たとえば以下のように記述した。

<form method="POST" action="./hoge.rb">
 一言メモ: <input name="var" size="40"><br>
 <input type="submit" value="SEND!">
 <input type="reset" value="reset">
</form>

ファイルの中味をPOSTするには、formenctype 属性を multipart/form-data に変える。

<form method="POST" enctype="multipart/form-data" action="./hoge.rb">
 一言メモ: <input name="var" size="40"><br><br>
 画像を選んでね: <input name="image" type="file">
 <input type="submit" value="SEND!">
 <input type="reset" value="reset">
</form>

HTMLで multipart/form-data を指定して入力させた値を受け取るCGIスクリプト、 すなわちRubyプログラムは、CGI変数の受け取りを以下のように変更する。

require "cgi"
cgi = CGI.new(:accept_charset => "UTF-8")

memo = cgi["var"].read			# CGI変数 var の受け取り(text)
photo_filename = cgi["image"].original_filename	# ファイル名の受け取り
photo_size = cgi["image"].size		# 送信ファイルサイズ取得
photo_data = cgi["image"].read		# 送信ファイルデータの受け取り

このように、実際のCGIフォームでの送信値を得るには read メソッドを介して行なう。type="file" だけでなく type="text"read メソッドで取得することに注意。

読み取った画像データをファイルに保存するにはたとえば以下のようにする。

open("ファイル名", "w") do |out|
  out.write cgi["image"].read
end

保存するファイル名は上書きに留意しつつ適切に決める。 なお、ファイルを保存するディレクトリはWebサーバの権限で書き込めるよう にしておく。そのため、画像データを書き出すディレクトリは あらかじめ決めて chmod 1777 しておくとよい。

画像投稿の実例

1MB以下の画像ファイル(JPEGまたはPNG)を投稿してみよ。

投稿画像選択:
一言説明:

ソース: filepost.rb

複数画像の投稿

html5に対応したブラウザのみの利用となるが、type="file"input 要素に multiple 属性を付けると、 複数のファイル選択をさせることが可能となる。

この場合、Rubyプログラムで受け取るCGI変数は、値を配列で受け取れる ように CGI#params を利用する。たとえばHTML側で、

<input name="memo" type="text">
<input name="memo" type="text">

のように同じCGI変数 memo で複数の値を送信することもできる。 これをRubyプログラム側で処理するには

require 'cgi'
cgi = CGI.new(:accept_charset => "UTF-8")
v_memo = cgi.params["memo"]

のようにする。v_memo[0] で1つ目のinputフォーム値が、 v_memo[1] で2つ目のinputフォーム値が受け取れるようになる。 これは他のtypeでも同様である。ただし、 enctype="multipart/form-data" の場合にはそれぞれ v_memo[0].read, v_memo[1].read のようにさらに read メソッドを呼んで実際のCGI変数値が取得できる。

以上のことを利用して、複数のファイルをまとめて投稿させ、 それらのサムネイル画像を生成し、サムネイルから元の画像にリンクした Webページを自動生成するCGIプログラムの例を以下に示す。 実際に複数の画像を与えてみよ。

投稿画像選択(複数画像OK):
タイトル:
本文:

ソース: multipost.rb


目次