[Up] [Next] [Previous]  [Home]

GIFs On the Fly

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

などがあります。

Ghostscript

Ghostscript (GS) は GNU の PostScript インタプリタです。GS の最大の特 徴は出力デバイスが豊富な事です。GS を使えば、PostScript で記述した図を、 GIF に出力する事が可能です。(Aladdin Ghostscript 3.12 にデバイスドライ バが含まれていますが、最新版には含まれていません。)

gd (GIFライブラリ)

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

このgdライブラリは、以下のAnonymous FTPサーバから入手できます。

ftp://isis.cshl.org/pub/gd
また、このライブラリを Perl5 で利用するためのパッケージモジュール GD.pm が以下のAnonymous 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を適当な場所にコピーします。

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

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 は Perl 5 が static ライブラリを使 用している場合と共有ライブラリを使用している場合とでは、インストール方 法が異なります。static ライブラリの場合には、$PERL5/ext/ の下に GD ラ イブラリを置いて、Perl 5 を作成するときと同じようにコンパイルしなけれ ばなりません。そのため、予めわかっていれば、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, "foo.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プログラムです。


GD.pmを使って作成した図
#!/usr/bin/perl

# gd.pm を使用する宣言です。
use GD;

# 200×100ピクセルの新しいイメージを作成します。
$im = new GD::Image(200,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(10,10,190,190,$black);

# 青枠の楕円をおきます。
$im-<arc(50,50,95,75,0,360,$blue);

# 四角を黄色に楕円を赤で埋めます。
$im-<fill(50,50,$red);
$im-<fill(100,50,$red);

# GIF を標準出力します。
print $im-<gif;

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="/cgi-bin/on-the-fly-gif.cgi">
これだけでは、ユーザからの要求を反映しないGIFの出力となります。そのた め、CGIスクリプトに何らかの引数を最初に与えてあげれば、ユーザからの要 求に反映したGIFを出力にすることができます。
<IMG SRC="/cgi-bin/on-the-fly-gif.cgi?argv1=m&argv2=n">
そして引数をフォーム形式で入力させるために、次のように処理させればよい ことがわかります。

<FORM ACTION="/cgi-bin/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="/cgi-bin/on-the-fly-gif.cgi$query">
</FORM>

最初の/cgi-bin/cgi-script は、ページを作るCGIスクリプトです。 /cgi-bin/on-the-fly-gif.cgi$queryは、インラインイメージを作成 するCGIスクリプトで、フォームで入力した値を引数($query)にして います。この$queryはスクリプトの一番最初に予め読み込んでおく ことが重要です。引数を渡しやすいように、METHODを GETとしてお きます。

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


GIFs On The Fly の例

インライン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="/cgi-bin/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"<<P>

<INPUT TYPE="submit">

</FORM>

<P>

<IMG SRC="/cgi-bin/colors_gif.cgi$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_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;
}

これで完成です。そして、このページを呼ぶポイントで初期値を引数として渡 すように設定しておきます。

<A HREF="/cgi-bin/colors.cgi?bred=255&bgreen=255&bblue=255&
tred=0&tgreen=0&tblue=0">オンザフライGIF</A>
スクリプトのテスト

GNU Plot

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

GNUPlot を使って GIF On the Fly を作成するCGIスクリプトをPerl で作成す る場合、次の点に注意します。

#!/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;

スクリプトのテスト

pgperl

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


[Up] [Next] [Previous]  [Home]