サムネイルの作り方

CGIテクニック集トップへ





概要

GDを利用し画像ファイルのサイズを変更し新しい画像ファイルを作成します。リサイズイメージ3画像ダウンロードなど当サイトで公開されているサムネイルを作成するCGI等で多数利用されています。 画像ファイルサイズを制限したサムネイルの作り方もご参照ください。

必用な処理

  1. 元の画像ファイルからオブジェクトを作成
  2. そのオブジェクトから画像ファイルのサイズを取得
  3. サイズ変更後の画像のオブジェクトを作成
  4. そのオブジェクトに元オブジェクトからサイズを変更して画像をコピーする
  5. サイズ変更後のオブジェクトをファイルに書き出す

サンプルコード

 use GD;
 
 my $im;
 $im =~ /\.jpe?g$/i and $im = GD::Image->newFromJpeg($imagefile,1);
 $im =~ /\.gif$/i   and $im = GD::Image->newFromGif($imagefile);
 $im =~ /\.png$/i   and $im = GD::Image->newFromPng($imagefile);
 $im =~ /\.gd$/i    and $im = GD::Image->newFromgd($imagefile);
 $im =~ /\.gd2$/i   and $im = GD::Image->newFromgd2($imagefile);
 
 my ($width, $height) = $im->getBounds();
 
 my $target_im = new GD::Image($new_width,$new_height,1);
 $target_im->copyResized($im,0,0,0,0,$new_width,$new_height,
                        $width,$height);
 
 open(IMAGE, "> $new_image");
 binmode(IMAGE);
 if ($imagefile =~ /\.jpe?g$/i){
     print IMAGE $target_im->jpeg(80);
 } elsif ($imagefile =~ /\.gif$/i) {
     print IMAGE $target_im->gif();
 } elsif ($imagefile =~ /\.png$/i) {
     print IMAGE $target_im->png();
 } elsif ($imagefile =~ /\.gd$/i) {
     print IMAGE $target_im->gd();
 } elsif ($imagefile =~ /\.gd2$/i) {
     print IMAGE $target_im->gd2();
 }
 close(IMAGE);

コードの解説

 use GD;

GDを定義します。GDのさまざまなメソッドを利用します。


 my $im;
 $im =~ /\.jpe?g$/i and $im = GD::Image->newFromJpeg($imagefile,1);
 $im =~ /\.gif$/i   and $im = GD::Image->newFromGif($imagefile);
 $im =~ /\.png$/i   and $im = GD::Image->newFromPng($imagefile);
 $im =~ /\.gd$/i    and $im = GD::Image->newFromgd($imagefile);
 $im =~ /\.gd2$/i   and $im = GD::Image->newFromgd2($imagefile);

$imagefileには画像ファイル名が入っていると仮定します。ファイルの拡張子によりファイルタイプを認識しGD::Image->newFromxxxによりそのファイルからオブジェクトを作成します。オブジェクトは$imに格納されます。

古いバージョンのGDではnewFromGifがサポートされていません。拡張子と実際の画像タイプが違う場合はGDからエラーがでます。ファイルサイズが0などとにかくGDを騙すようなファイルの場合にはGDがエラーになります。これらのエラーはFatalでスクリプト自体が動かなくなります。サーバーのerror log等から原因を解明しエラーの原因となるファイルを修正するとよいでしょう。

 $im = GD::Image->newFromJpeg($imagefile,1);

newFromJpegメソッドの第二引数はTruecolor指定の際に1にします。ドキュメントにはファイルからオブジェクトを作成する場合は自動的にTruecolorになると書いてありますが作成された画像を見ると画質に違いがあるのでここでは指定します。

 my ($width, $height) = $im->getBounds();

getBoundsメソッドにより画像サイズを取得します。$widthに幅、$heightに高さ情報が入ります。

 my $target_im = new GD::Image($new_width,$new_height,1);

$new_widthと$new_heightにはサイズ変更後の新しい幅と高さが入っています。そのサイズで新しい画像のオブジェクトを作成します。第三引数はTruecolorでイメージを作るときに1を指定します。

 $target_im->copyResized($im,0,0,0,0,$new_width,$new_height,
                        $width,$height);

copyResizedメソッドにより元画像のオブジェクトをサイズを変更して新オブジェクトにコピーします。参考までにcopyResizedは、

 $im->copyResized($sourceImage,$dstX,$dstY,
                     $srcX,$srcY,$destW,$destH,$srcW,$srcH)
 
 $sourceImage : 元の画像オブジェクト
 $dstX        : ターゲット画像の開始座標X
 $dstY        : ターゲット画像の開始座標Y
 $srcX        : 元画像の開始座標X
 $srcY        : 元画像の開始座標Y
 $destW       : ターゲット画像の幅
 $destH       : ターゲット画像の高さ
 $srcW        : 元画像の幅
 $srcH        : 元画像の高さ

の引数を取ります。

 open(IMAGE, "> $new_image");
 binmode(IMAGE);
 if ($imagefile =~ /\.jpe?g$/i){
     print IMAGE $target_im->jpeg(80);
 } elsif ($imagefile =~ /\.gif$/i) {
     print IMAGE $target_im->gif();
 } elsif ($imagefile =~ /\.png$/i) {
     print IMAGE $target_im->png();
 } elsif ($imagefile =~ /\.gd$/i) {
     print IMAGEfile $target_im->gd();
 } elsif ($imagefile =~ /\.gd2$/i) {
     print IMAGE $target_im->gd2();
 }
 close(IMAGE);

ターゲットオブジェクトをファイルに書き出します。元のファイルと同じフォーマットの画像ファイルを作成するために拡張子でフォーマットを判断しています。元のファイルと同じフォーマットである必要はないので変換したい場合はここでできます。 作成された画像ファイルはサイズが変更されたサムネイルとなっています。

  $target_im->jpeg(80);

jpegメソッドの引数はQualityです。0から100までの数字になります。数字が大きいと画質はいいですがファイルサイズが大きくなります。省略するとjpegメソッドがちょうどいい画質を選ぶそうですが風景画像による経験からするとデフォルトではあまりいい画像になりません。100ではファイルサイズが大きすぎるので80から90がいいでしょう。

関連するCGIテクニック

画像サイズの取得
Image::Sizeを使って画像サイズを取得する方法
画像サイズ変更の仕方
画像ファイルサイズを制限したサムネイルの作り方
画像プリロードの仕方
Exif情報の取得の仕方