CGIスクリプトの例 フォームとCGI目次 サーバサイドインクルード

GIFs on the Fly

WWWでイメージは大きな役割を持っていますが、ここではその時点で処理したイメージを見せるグラフやイメージの作成方法をいくつかご紹介します。GIFイメージは以下のプログラム・ライブラリやGIFを吐くグラフ・プログラムを利用することによって、その場でGIFを作成しブラウザ(閲覧ソフト)へ表示することが可能です。これらを "GIFs On the Fly" と呼び、以下のようなものがあります。

gdライブラリ(CまたはPerl5)
GNU Plot
pgperl
Netpbm

gd (GIFライブラリ)

gdはコールドスプリングハーバ研究所のQuest Protein Database Centerが開発した GIF作成用のCライブラリです。WWWの多くの画像ファイルはGIFフォーマットが使われていますが、このライブラリを使用したプログラムは実行すれば自動的に(on the fly)GIFファイルが作成できます。gdライブラリで作成できるGIFは以下の図形です。

ポリゴン
多角形
インタレースGIF
文字
このgdライブラリは以下のFTPサーバから入手できます。

ftp://isis.cshl.org/pub/gd
また、このライブラリを Perl5 で利用するためのパッケージモジュールGD.pm が以下のFTPサーバから入手できます。

http://www-genome.wi.mit.edu/ftp/pub/software/WWW/GD.html
ftp://ftp.lab.kdd.co.jp/infosystems/misc/tools/GD.pm.tar.Z
ここでは手軽に利用できるPerl5でGD.pmを利用する方法を説明します。

GDのインストール

GD.pmを利用するには、まずgdライブラリをインストールしておく必要があります。gdを入手し、付属の Makefileを自分のシステムに合わせて編集し、コンパイルします。ヘッダファイル(gd.h, gdfontl.h,gdfonts.h)と作成されたlibgd.aを適当な場所にコピーします。

次にPerl5をインストールします。Perl5は以下のサイトから入手できます。

ftp://ftp.lab.kdd.co.jp/lang/perl/CPAN/src/5.0/
Perl5を展開したら、付属のConfigureプログラムを実行し、質問に答えていきます。最終的に Config.h と Makefile が生成されるので、makeと実行し、コンパイルします。正常にコンパイルが終れば、インストール("make install")を行います。
	
	
	% gunzip -c perl5.001.tar.gz | tar xf -
	% cd perl5.001
	% ./Configure
	  :
	% make
	% make install
	
	
次にGD.pmのインストールです。GD.pmはPerl5がstaticライブラリを使用している場合と共有ライブラリを使用している場合とでは、インストール方法が異なります。staticライブラリの場合には、$perl5/ext/の下にGDライブラリを置いて、Perl5を作成するときと同じようにコンパイルしなければなりません。そのため、あらかじめわかっていれば、GD.pmを埋め込んでおいたほうがいいでしょう。共有ライブラリの場合は、$perl5/extにGD.pmを展開して置いて、perl5 Makefile.plを実行し、make 、make install を行います。
	
	
	% cd perl5.001/ext/GD
	% perl5 Makefile.pl
	% make
	% make install
	
	
インストールが完了したら、最後に付属のデモスクリプトを実行します。

demos/skkskdl.pl | xv -
正常に画面が Xウィンドウ上に表示されれば、インストールが完了です。

GD.pmの機能

GD.pmはgdライブラリと同じ機能を持ちます。詳しい説明はマニュアルに譲るとして、ここではよく使われる機能を説明しておきましょう。

GD.pmでは3つのクラスが定義されています。

GD::Image
イメージの作成を行うクラスです
GD::Font
フォント、テキストの作成を行うクラスです
GD::Polygon
ポリゴンを作成するクラスです
イメージの作成

new
GD::Image::new(width,height) class method
新しい、空のイメージを作成します。
(例)
$img = new GD::Image(100,100) || die "not create image";
newFromGif
GD::Image::newFromGif(filehandle) class method
GIFファイルを読み込んで、イメージを作成します。
(例)
open (GIF, "yokochin.gif") || die "Not open";
$img = newFromGIF GD::Image(GIF) || die;
close GIF;
色の制御

colorAllocate
GD::Image::colorAllocate(red,green,blue) object method
イメージの色を割り当てます。
(例)
$black = $img->colorAllocate(0,0,0); # 黒
$white = $img->colorAllocate(255,255,255); # 白
$gray = $img->colorAllocate(127,127,127); # 灰色
colorDeallocate
GD::Image::colorDeallocate(colorindex) object method
色の再割り当てを行う際に使用し、前に割り当てた色を削除します。
(例)
$img->colorDeallocate($gray);
$gray = $img->colorAllocate(255,127,127);
colorClosest
GD::Image::colorClosest(red,green,blue) object method
指定されたカラーテーブルに近い色のインデックスを返します。
(例)
$apricot = $img->colorClosest(255,200,180);
colorExact
GD::Image::colorExact(red,green,blue) object method
指定されたカラーテーブルに一致した色のインデックスを返します。一致しない場合、-1を返します。
(例)
$rosey = $img->colorExact(255,100,80);
warn "Everything's coming up roses.\n" if $rosey >= 0;
getPixel
GD::Image::getPixel(x,y) object method
指定されたポイントのカラーテーブルインデックスを返します。rgb()と組み合わせて色がわかります。
(例)
$colorindex = $img->getPixel(20,100);
($r,$g,$b) = $img->rgb($colorindex);
rgb
GD::Image::rgb(colorIndex) object method
指定されたカラーインデックスの3原色リストを返します。
(例)
@RGB = $img->rgb($gray);
transparent
GD::Image::transparent(colorindex) object method
透明化する色を指定します。背景色を透明にする場合に用いられます。
(例)
open (GIF, "test.gif");
$im = newFromGif GD::Image(GIF);
$white = $im->colorClosest(255,255,255); #白をみつけます
$im->transparent($white);
print $im->gif;
描画コマンド

line
GD::Image::line(x1,y1,x2,y2,color) object method
座標(x1,y1)から(x2,y2)に指定されたcolor色で線を描画します。
(例)
$img->line(0,0,150,150,gdBrushed);
rectangle
GD::Image::rectangle(x1,y1,x2,y2,color) object method
左上座標(x1,y1)と右下座標(x2,y2)を指定された色で四角を描画します。
(例)
$img->rectangle(10,10,150,150,$rose);
gd.pmを使った例

ここでご紹介するのは四角と楕円を作るGDプログラムです。

	
	
	#!/usr/bin/perl
	
	# GD.pm を使用する宣言です。
	use GD;
	
	# 200×100ピクセルの新しいイメージを作成します。
	$im = new GD::Image(120,100);
	
	# ここで使用する色を割り当てます。
	$white = $im-<colorAllocate(255,255,255);
	$black = $im-<colorAllocate(0,0,0);
	$red = $im-<colorAllocate(255,0,0);
	$blue = $im-<colorAllocate(0,0,255);
	$yellow = $im-<colorAllocate(255,255,0);
	
	# 透明化する色とインタレース化を指定します
	$im-<transparent($white);
	$im-<interlaced('true');
	
	# 黒枠の四角をおきます。
	$im-<rectangle(30,10,110,90,$black);
	
	# 青枠の楕円をおきます。
	$im-<arc(50,50,95,75,0,360,$blue);
	
	# 四角を黄色に楕円を赤で埋めます。
	$im-<fill(50,50,$yellow);
	$im-<fill(100,50,$red);
	
	# GIFを標準出力します。
	print $im-<gif;
	
	
 
GD.pmを使って作成した画像


 

GIFs on the flyのCGIスクリプト例

GIFs on the flyを行う場合、GIFイメージを外部イメージとして表示するか、インラインイメージで表示するか決める必要があります。まず、外部イメージで表示する場合、作成したGIFイメージを"Content-type:image/gif"の後に出力させればよいだけです。Perlで行う場合、次のよ うな骨組みとなります。
	
	
	#!/usr/bin/perl
	
	(入力処理)
	(データ処理)
	
	print "Content-type: image/gif\n\n";
	
	(GIFを標準出力)
	
	
インラインイメージを出力する場合、<img>タグを使わなければなりません。<img>タグのsrc属性でURLが指定できますから、このURLにCGIスクリプトを指定することで、それ(CGIスクリプトの出力)がインラインイメージとなります。
<img src="../script/on_the_fly_gif.cgi">
これだけではユーザからの要求を反映しないGIFの出力となるため、CGIスクリプトへ最初に何らかの引数を与えておきます。そうすれば、ユーザからの要求を反映したGIFの出力が可能です。
<img src="../scripts/on_the_fly_gif.cgi?argv1=m&argv2=n">
そして引数をフォーム形式で入力させるため、次のように処理させればよいことがわかります。
	
	
	<form action="../scripts/cgi-script" method=get>
	<input type="text" name="Name1" value="Value1"><br>
	<input type="text" name="Name2" value="Value2"><br>
	<input type="submit"><p>
	<img src="../scripts/on-the-fly-gif.cgi$query">
	</form>
	
	
最初のcgi-scriptはページを作るCGIスクリプトであり、on-the-fly-gif.cgi$queryはインラインイメージを作成するCGIスクリプトで、フォームで入力した値を引数($query)にしています。この$queryは、あらかじめスクリプトの1番最初に読み込んでおくことが重要です。そして、引数を渡しやすいようmethodをgetとしておきます。

$query = "?".$env{'query_string'} if $env{'query_string'} ne "";
これは、query_string環境変数がnullでなければ、頭に"?"を付けた値を $queryにセットする式です。
それでは、GDを使って指定された3原色をインラインGIFイメージで表示するCGIスクリプトを作って見ます。まず、初期ページを次のようなイメージになるよう設計します。

インラインGIFイメージを作成するため、初期ページもCGIの中で作らなければなりません。そこで、まず初期ページを作るためのCGIスクリプトです。

	
	
	#!/usr/bin/perl
	
	print "Content-type: text/html\n\n";
	
	# 初期値読み
	$query = "?".$env{'query_string'} if $env{'query_string'} ne "";
	
	# Get form data ...
	%form = &read_input;
	
	$bred=&decimal($form{'bred'});
	$bgreen=&decimal($form{'bgreen'});
	$bblue=&decimal($form{'bblue'});
	$tred=&decimal($form{'tred'});
	$tgreen=&decimal($form{'tgreen'});
	$tblue=&decimal($form{'tblue'});
	
	print <<eod;
	
	<head>
	<title>Autocreate Color Table</title>
	</head>
	<body>
	<h1>Automate color GIF image</h1>
	
	<hr>
	
	<form action="../scripts/colors.cgi" method="get">
	
	<h3>Background Color (Decimal 0-255)</h3>
	Red <input type="text" name="bred" size=3 maxlength=3 value="$bred">
	Gree <input type="text" name="bgreen" size=3 maxlength=3 value="$bgreen">
	Blue <input type="text" name="bblue" size=3 maxlength=3 value="$bblue">
	
	<h3>Text Color (Decimal 0-255)</h3>
	Red <input type="text" name="tred" size=3 maxlength=3 value="$tred">
	Gree <input type="text" name="tgreen" size=3 maxlength=3 value="$tgreen">
	Blue <input type="text" name="tblue" size=3 maxlength=3 value="$tblue">
	
	<input type="submit">
	
	</form>
	
	<p>
	
	<img src="../images/colors.gif$query">
	
	</body>
	eod
	
	#
	
	sub read_input
	{
	    local ($buffer, @pairs, $pair, $name, $value, %form);
	    # Read in text
	    $env{'request_method'} =~ tr/a-z/A-Z/;
	    if ($env{'request_method'} eq "post")
	    {
		read(stdin, $buffer, $env{'content_length'});
	    } else
	    {
		$buffer = $env{'query_string'};
	    }
	    @pairs = split(/&/, $buffer);
	    foreach $pair (@pairs)
	    {
		($name, $value) = split(/=/, $pair);
		$value =~ tr/+/ /;
		$value =~ s/%(..)/pack("C", hex($1))/eg;
		$form{$name} = $value;
	    }
	    %form;
	}
	
	# 0〜255までの整数が有効
	sub decimal
	{
	    local($cr)=@_;
	    $icr=int($cr); # 整数化
	    if (0 <= $icr && $icr < 256) {
		return $icr;
	    }
	    else {
		return 255;
	    }
	}
	
	
次にインラインGIFを作る部分のCGIスクリプトです。
	
	
	#!/usr/bin/perl
	
	use GD;
	
	# 初期値読み
	
	%form = &read_input;
	
	print "Content-type: image/gif\n\n";
	
	$bred=$form{'bred'}		if defined( $form{'bred'} );
	$bgreen=$form{'bgreen'}		if defined( $form{'bgreen'} );
	$bblue=$form{'bblue'}		if defined( $form{'bblue'} );
	$tred=$form{'tred'}		if defined( $form{'tred'} );
	$tgreen=$form{'tgreen'}		if defined( $form{'tgreen'} );
	$tblue=$form{'tblue'}		if defined( $form{'tblue'} );
	
	# create a new image
	$im = new GD::Image(500,30);
	
	# aloocate some colors
	$bcolorbox=$im->colorAllocate($bred,$bgreen,$bblue);
	$tcolorbox=$im->colorAllocate($tred,$tgreen,$tblue);
	
	$im->interlaced('true');
	
	# Draw rectangle
	$im->rectangle(0,0,499,29,$colorbox);
	
	# Draw Text
	$im->string(gdLargeFont,100,10,"ABCDEFGHIJKLMNOPQRSTUVWXYZ",$tcolorbox);
	
	print $im->gif;
	
	#
	sub read_input
	{
	    local ($buffer, @pairs, $pair, $name, $value, %FORM);
	    # Read in text
	    $env{'request_nethod'} =~ tr/a-z/A-Z/;
	    if ($env{'request_method'} eq "post")
	    {
		read(stdin, $buffer, $env{'content_length'});
	    } else
	    {
		$buffer = $env{'query_string'};
	    }
	    @pairs = split(/&/, $buffer);
	    foreach $pair (@pairs)
	    {
		($name, $value) = split(/=/, $pair);
		$value =~ tr/+/ /;
		$value =~ s/%(..)/pack("C", hex($1))/eg;
		$form{$name} = $value;
	    }
	    %form;
	}
	
	
これで完成です。そして、このページを呼ぶポイントで初期値を引数として渡すように設定しておきます。
	
	
	<a href="../scripts/colors.cgi?bred=255&bgreen=255&bblue=255&tred=0&tgreen=0&tblue=0">
	オンザフライGIF</a>
	
	

スクリプトのテスト

GIFs on the Flyスクリプトのテスト

GNU Plot

GNUPlotは、さまざまなグラフを描画するツールです。たとえば、sin()カーブを描画する場合、下記のCGIスクリプトを使用します。そして、一定の時間ごとにデータ更新をしている場合も、GNUPlotを使い、たえずグラフ化することができます。

なお、GNUPlotを使いGIF On the FlyのCGIスクリプトをPerlで作成する場合、パイプ機能を使用するため、Perlに標準出力へバッファリングさせないようにする点と、GNUPlotはGIFを直接出力できないので、PBM形式の出力を行うように設定し(set term pbm color)、NetpbmパッケージのppmtogifでGIFへ変換する点に注意して下さい。

	
	
	#!/usr/bin/perl
	# Filename: nph-plot.cgi
	
	$gnuplot = '/usr/local/bin/gnuplot';
	$ppmtogif = '/usr/X11R6/bin/ppmtogif';
	
	$|=1;
	
	print "HTTP/1.0 200 Okay\n";
	print "Content-type: image/gif\n\n";
	
	open (graph,"| $gnuplot | $ppmtogif") || die ;
	print graph <<end;
	set term pbm color
	plot sin(x)
	end
	
	close graph;
	
	
スクリプトのテスト

GIFs on the Flyスクリプトのテスト

pgperl

pgperl は GNUPlot のようなプログラムで、Perl の中にプロッティング機能が組み込まれています。なお、pgpperlのコンパイルにはFortran(f77)コンパイラが必要となります。



Copyright (C) 1996-2003 by Yasukazu Yokoi. All Rights Reserved.