PHP

PHPで透過png画像を結合してみました。

2017/04/10

PHPを使って透過png画像を結合」する機会があったので記事に残しておこうかと。

概要

500x500の画像19枚(a.png~s.png)を結合して下記の1枚の画像にしてみます。

使用する素材は こちら からダウンロード可能です。

さっそくソース

<?php

$arr = range('a', 's');

foreach ($arr as $key => $val) {
  if ($key === 0) {
    $canvas = imagecreatefrompng($val . '.png');
    imagesavealpha($canvas, true);
    continue;
  }
  ${$val} = imagecreatefrompng("{$val}.png");
  imagecopy($canvas, ${$val}, 0, 0, 0, 0, 500, 500);
  imagedestroy(${$val});
}

$fileName = implode("", $arr);
imagepng($canvas, $fileName . '.png');
 

解説

$arr = range('a', 's');

rangeでaからsの配列を作ります。

foreach ($arr as $key => $val) {
  if ($key === 0) {
    $canvas = imagecreatefrompng($val . '.png');
    imagesavealpha($canvas, true);
    continue;
  }
  ${$val} = imagecreatefrompng("{$val}.png");
  imagecopy($canvas, ${$val}, 0, 0, 0, 0, 500, 500);
  imagedestroy(${$val});
}

作った配列をforeachで回していきます。
6行目の$key === 0 つまり1つ目の値(a)を使って 7行目のimagecreatefrompngでa.pngから土台となる画像$canvasを生成します。

8行目のimagesavealphaで透過情報を保存するフラグを設定しています。これをしないと背景部分が真っ黒になりますので注意が必要です。

a.png以外は11行目のimagecopyで土台画像$canvasの上に重ねていきます。第一引数に土台画像、第二引数に結合する画像、以降は位置やサイズです。今回は全て500x500の画像なので 「0, 0, 0, 0, 500, 500」になっていますが、違うサイズの画像を結合させる場合はこの部分の調整が必要です。値は「土台画像のx座標, 土台画像のy座標, 結合する画像のx座標, 結合する画像のy座標, 結合する画像の幅, 結合する画像の高さ」になります。画像のサイズはgetimagesizeで取得できると思います。

13行目でメモリ解放しています。

$fileName = implode("", $arr);
imagepng($canvas, $fileName . '.png');

16行目はファイル名の指定です。今回はa~sを結合しています。
17行目のimagepngでサーバーに保存しています。第二引数に保存先のディレクトリを指定することもできます。

サーバーに保存せずにブラウザに表示させたい場合は、16・17行目を以下に変更することで可能になります。

ob_start();
imagepng($canvas);
imagedestroy($canvas);
$canvas = ob_get_clean();
echo "<img src='data:image/png;base64,".base64_encode($canvas)."'>";

最後に

かなり需要が少ない内容になったと思いますが、もしこの記事が誰かの役に立ったら嬉しいです。
サーバーに保存せずにダウンロードさせる方法がないか色々試したんですが、今回は見つけることができなかったので見つかったら追記したいと思います。

-PHP