PHP+GDでアバターの着せ替え

最近、仕事でGD使うことが多くなって実はそれを利用してアバターの合成とかやってたりします。
アバターとはYahoo!等に設定されている着せ替え可能なキャラクターのことですね。FLASHやアプリだとパーツごとに渡してあとはFLASH/アプリに任せれば良いのですが、ウェブページの場合は最終的に一枚の画像に合成しないといけないんですね。PHPで合成するなら簡単、透過画像も透過のまま合成できます。但しそのままでは出力時に透過がなくなるので透過を残す場合はちょっと工夫が必要です。

背景と前景の画像ピクセルサイズはが同一の場合のサンプル

// 背景にする画像を読み込み(PNG画像の場合)
$backimg = imagecreatefrompng(‘background.png’);

// 画像サイズの取得
$size = getimagesize(‘background.png’);

// 前景にする画像を読み込み
$frontimg = imagecreatefrompng(‘front.png’);

// 合成処理 ($backimgの上に$frontimgを合成して結果が$frontimg$backimgに上書きされる)
imagecopymerge( $backimg, $frontimg, 0,0,0,0, $size[0], $size[1], 100);

// 背景と前景をあわせても透過部分が残る場合は出力時に透過にするように処理(特殊)
// 透過色を255,0,255に定義
$white = imagecolorallocate( $frontimg$backimg, 255,0,255);
// 先程の設定色を透過色として設定
imagecolortransparent($frontimg$backimg,$white);
// 透過色で塗りつぶしてみる
imagefill($frontimg$backimg,0,0,$white);

// ファイルに書き出しの場合
imagepng($frontimg$backimg,’marge.png’);

// 画像として画面に出力の場合
header(“Content-Type: image/png”);
imagepng($frontimg$backimg);

上記の方法は透過パレット色を指定しない場合で(0,0)の位置が透過対象でない場合失敗します。透過色を統一して指定する場合はimagefillが不要になると思います。その場合imagecolorecact等で取得したインデックスでないと失敗します。(その方法は次回に)

またこの方法ではアニメーションができない。リアルタイムで反映させたりアニメーションさせるのであればJavaScriptになるのかなー?サイト製作はPerl/PHPばかり多くてCSS/JavaScriptには手が回らない。 orz…

追記:2008年12月1日
長らく誤記を放置してました。すみません。途中でマージ後の出力先を勘違いしていた模様です。随分前のエントリーの為透過処理辺りのフォーマットによるルールとか今では記憶が怪しい・・・。

実際に動作するソースは次のエントリーにリンクを張っていますのでこちらも参照お願いします。