PHPで画像を合成する

(1/1)
東京アメッシュは、東京を含む関東地方の雨の様子をほぼリアルタイムで確認することができるサイトだ。東京都水道局が運営している。
ゲリラ豪雨のツイートをするために利用しようとしたのだが、画像は3枚のレイヤから成っており、そのままでは投稿できない。そこで、PHPを使って1枚の画像に合成してみることにした。

(2022年4月3日)PHP8対応,リファラ・チェック改良

サンプル・プログラムの実行例

PHPで画像を合成する
PNG形式画像として画面に表示する。左下に、データの取得日時を埋め込む。
URLオプションとして "tokyoAme.php?filename=ame.png" のように指定すると、PNGファイル "ame.png" を保存(ダウンロード)できる。

サンプル・プログラム

圧縮ファイルの内容
tokyoAme.phpサンプル・プログラム本体

解説:準備

  32: //フォント:各自の環境に合わせて
  33: define('FONT', '/virtual/pahoo/public_html/common/font/ipamp.ttf');

今回もGD ライブラリを用いる。

画像にデータの取得日時を記載するため、テキストを埋め込む必要がある。
PHPでTrueTypeフォントを利用する」で解説したとおり、1TurTypeフォント・ファイルを定数 FONT に定義しておく。
また、文字エンコードはUTF-8にする。

解説:画像合成

  94: /**
  95:  * 東京アメッシュの画像を表示/保存
  96:  * @param   string $fname = 保存ファイル名(常にPNG形式)/'':画面表示
  97:  * @return  string メッセージ/FALSE=取得失敗
  98: */
  99: function tokyoAme($fname='') {
 100:     $ti = (int)((time() - 60 * 10) / (60 * 10)) * (60 * 10);
 101:     $msg = sprintf("%04d年%02d月%02d日 %02d時%02d分", date('Y', $ti), date('m', $ti), date('d', $ti), date('H', $ti), date('i', $ti));
 102: 
 103:     $url1 = 'https://tokyo-ame.jwa.or.jp/map/map000.jpg';   //地形
 104:     $url2 = 'https://tokyo-ame.jwa.or.jp/map/msk000.png';   //県境
 105:     $url3 = 'https://tokyo-ame.jwa.or.jp/mesh/000/' . date('YmdHi', $ti. '.gif';  //降雨情報
 106: 
 107:     //画像サイズ
 108:     if (($arr = getimagesize($url1)) == FALSE)  return FALSE;
 109:     $width  = $arr[0];
 110:     $height = $arr[1];
 111: 
 112:     //画像合成
 113:     if (($img1 = @imagecreatefromjpeg($url1)) == FALSEreturn FALSE;
 114:     if (($img2 = @imagecreatefrompng($url2)) == FALSE)  return FALSE;
 115:     if (($img3 = @imagecreatefromgif($url3)) == FALSE)  return FALSE;
 116: 
 117:     imagecopy($img1, $img2, 0, 0, 0, 0, $width, $height);
 118:     imagecopy($img1, $img3, 0, 0, 0, 0, $width, $height);
 119: 
 120:     //日時合成
 121:     $color = imagecolorallocate($img1, 0x00, 0x00, 0x40);
 122:     imagettftext($img1, 12, 0, 5, $height - 5, $color, FONT, $msg);
 123: 
 124:     //画像表示
 125:     if ($fname == '') {
 126:         header('Content-Type: image/png');
 127:         imagepng($img1);
 128:     //画像保存
 129:     } else {
 130:         header('Content-Type: image/png');
 131:         header('Content-Disposition: attachment; filename=' . $fname .'"');
 132:         imagepng($img1);
 133:     }
 134: 
 135:     //画像破棄
 136:     imagedestroy($img1);
 137:     imagedestroy($img2);
 138:     imagedestroy($img3);
 139: 
 140:     return $msg;
 141: }

合成する画像は $url1$url3 の3枚である。
このうち、$url3のファイル名は以下の通り。10分間隔で更新されている。
  年(4桁)月(2桁)日(2桁)時(2桁)分(2桁).gif

まず、関数  imagecreatefromjpeg ,  imagecreatefrompng ,  imagecreatefromgif  を使い、3枚の画像をメモリに取り込む。これらの関数はURL上の画像も取り込むことができるので便利だ。

画像合成は、関数  imagecopy  を用いて行う。2枚の画像を1枚の画像に合成できる。
画像の大きさを指定する必要があるので、あらかじめ関数  getimagesize  を用いて画像の幅と高さを取得しておく。このとき同時に、画像の存在可否をチェックしている。

画像へ日時を埋め込むには、関数  imagettftext  を用いている。

合成した画像 $img1 は、関数  header  と  imagepng  を用いてPNG画像としてブラウザ上に表示するか、保存を行う。

本ユーザー関数 tokyoAme に引数が指定されていたら、ローカルドライブにファイル名 $fname で保存する。

最後に、関数  imagedestroy  を用いてメモリを解放する。

参考サイト

(この項おわり)
header