導入
Web開発において、動的に画像を生成してSNSシェア用画像(OGP)を作成したり、複数の素材を組み合わせてコラージュ画像を作成したりするケースは少なくありません。PHPの標準ライブラリであるGDを活用すれば、サーバーサイドで画像加工が可能です。今回は、フォルダ内の画像をランダムに配置して一枚のタイル状画像を作成する方法を解説します。この手法は、バリエーション豊かなサムネイルを自動生成する際などに非常に有用です。
基礎知識
PHPで画像処理を行う際に最も広く使われているのがGDライブラリです。GDを使うと、画像の生成、リサイズ、合成(コピー)、保存といった一連の処理をプログラムで行えます。今回の実装のポイントは「リソースの管理」です。画像を開くたびにメモリを消費するため、不要になった画像リソースはimagedestroy()で適切に解放することが、メモリ不足を防ぐための鉄則です。
実装/解決策
画像をタイル状に敷き詰める際の論理的ステップは以下の通りです。
1. 指定ディレクトリから画像パスを取得し、各画像を読み込む。
2. 読み込み時に指定サイズに合わせてリサイズ(サムネイル化)しておく。
3. 生成したいキャンバスの行列を計算し、配置座標の組み合わせリストを作成する。
4. シャッフルした画像リストをループで回し、キャンバスにコピーしていく。
5. 画像が足りない場合は再度リストをシャッフルして再利用する。
サンプルプログラム
以下のコードは、指定ディレクトリの画像を読み込み、600×600のキャンバスにランダム配置する実例です。
$thumb, ‘w’ => $tw, ‘h’ => $th];
}
$images = [];
foreach (glob($dir . “.{jpg,png,gif}”, GLOB_BRACE) as $file) {
$images[] = load_image($file, $block_size);
}
// キャンバス作成
$canvas = imagecreatetruecolor($width, $height);
$max_x = ceil($width / $block_size);
$max_y = ceil($height / $block_size);
// 座標の計算と配置
for ($x = 0; $x < $max_x; $x++) {
for ($y = 0; $y < $max_y; $y++) {
shuffle($images); // 毎回ランダムに選択
$img = $images[0];
// 中央揃えで配置
imagecopy($canvas, $img['resource'],
$x $block_size - ($img['w'] - $block_size) / 2,
$y $block_size - ($img['h'] - $block_size) / 2,
0, 0, $img['w'], $img['h']);
}
}
// 出力
header("Content-type: image/jpeg");
imagejpeg($canvas, null, 80);
imagedestroy($canvas);
?>
応用・注意点
メモリ制限に注意: 多くの画像を同時に読み込むと、PHPのmemory_limitに抵触する可能性があります。大量の画像を扱う場合は、読み込む段階でサムネイル化してメモリを節約するか、ImageMagickへの切り替えを検討してください。また、imagedestroy()を忘れずに行うことで、ループ処理中のメモリリークを防ぐことができます。本番環境では、生成した画像をキャッシュ(ファイル保存)して、リクエストごとに再生成しない仕組みを構築するのが最も効率的です。