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は以下の図形です。
このgdライブラリは以下のFTPサーバから入手できます。
- ポリゴン
- 線
- 多角形
- インタレースGIF
- 文字
ftp://isis.cshl.org/pub/gdまた、このライブラリを Perl5 で利用するためのパッケージモジュールGD.pm が以下のFTPサーバから入手できます。
http://www-genome.wi.mit.edu/ftp/pub/software/WWW/GD.htmlここでは手軽に利用できるPerl5でGD.pmを利用する方法を説明します。
ftp://ftp.lab.kdd.co.jp/infosystems/misc/tools/GD.pm.tar.ZGDのインストール
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;
gd.pmを使った例
- 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プログラムです。
#!/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>スクリプトのテスト
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;スクリプトのテスト
pgperl
pgperl は GNUPlot のようなプログラムで、Perl の中にプロッティング機能が組み込まれています。なお、pgpperlのコンパイルにはFortran(f77)コンパイラが必要となります。