Webエンジニア 新人日記

Webエンジニアになりました。元々はCOBOLやらBASICやらでプログラムしてました。C言語やVisualBasicは趣味でやっていましたが、久々に現場復帰ということです。資格はエンベデッドスペシャリスト、DBスペシャリスト、ネットワークスペシャリスト、セキュリティスペシャリスト、システムアーキテクト、プロジェクトマネージャ他を所有

【PHP】GDを使って画像に文字を埋め込む

グラフィックライブラリGDを使って、テンプレート画像に文字を埋め込むことを考えてみる。

GDを使ってPHPで文字を書き込む場合、呼び出し元は画像ファイルを表示するのと同じ要領で
imgタグを使って表示する。

<img src="image.php">

実際に表示する側。例えば、バナーに日程を埋め込んでいたものを自動で変更するような場合。
呼び出し元で動的に変更する場合もあるけど、たくさんあると非常に面倒で手間暇もかかる。

全体構造から

//日程の配列
//次回の日程を検索するため
$nitteiarray=array(
'2016-09-01',
'2016-10-02',
'2016-11-03',
'2016-12-04',
'2017-01-05',
'2017-02-06'
);
$week = array('日', '月', '火', '水', '木', '金', '土');


//画像に埋め込む日付を設定
$target_day = "";
$today = date("Y-m-d");
foreach($nitteiarray as $nittei){
	if(strtotime($today) <= strtotime($nittei)){
		$target_day = $nittei;
		break;
	}
}

//埋め込む文字の設定
//第n回 n月d日(曜日)
if($target_day != ""){
	$dispday = '第' . (array_search($target_day, $nitteiarray) + 1) . '回  ';
	$dispday .= date('n月j日', strtotime($target_day));
	$dispday .= '(' . $week[date('w', strtotime($target_day))] . ')';
} else {
	$dispday = (date("Y", strtotime($nitteiarray[0])) + 1) . '年度の日程は未定です';
}

//フォントファイル(環境により読み取るディレクトリが変わる)
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
	$font = '/usr/home/xxxxx/fonts/ipag.ttf';
} else {
	
	$font = "c:\\windows\\fonts\\ipag.ttf";
}

//OSにより、文字のエンコードを変更する
$dispday = con($dispday);

$image = imagecreatefromjpeg('./images/template.jpg');
$blue = imagecolorallocate($image, 0,0,255);
$result = imagettftext($image, 20, 0, 20, 85, $blue, $font, $dispday);

header("Content-type: image/jpeg");
imagejpeg($image, NULL, 80);
imagedestroy($image);

いくつか、ピンポイントで説明。

//フォントファイル(環境により読み取るディレクトリが変わる)
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
	$font = '/usr/home/xxxxx/fonts/ipag.ttf';
} else {
	
	$font = "c:\\windows\\fonts\\ipag.ttf";
}

Windows環境とLinux環境ではフォントの置き場所が変わる。ローカルでテストしてからLinuxでテストする時にフォントディレクトリを変更するのが面倒なので。

//OSにより、文字のエンコードを変更する
$dispday = con($dispday);

自前関数を使っている。
Linuxの場合、全角文字はUTF-8以外でないと文字化けするみたい。
逆にWindowsUTF-8でないと文字化けらしい。
ソースファイルをUTF-8にする手もあるらしいけど、それもアホらしい。
その中身は

function con($arg1){
	if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
		return(mb_convert_encoding($arg1, 'SJIS'));
	} else {
		return($arg1);
	}
}	
$image = imagecreatefromjpeg('./images/template.jpg');

テンプレートファイルを読み込む。

$blue = imagecolorallocate($image, 0,0,255);
$result = imagettftext($image, 20, 0, 20, 85, $blue, $font, $dispday);

イメージに、実際に文字を書き込む所。
imagettftextの引数は
第1・・・imagecreatefromjpegで読み込んだテンプレートファイル
第2・・・フォントサイズ
第3・・・角度
第4・・・位置(X座標)
第5・・・位置(Y座標)
第6・・・imagecolorallocateで指定した色
第7・・・フォントへのパス
詳しくは
PHP: imagettftext - Manual

header("Content-type: image/jpeg");
imagejpeg($image, NULL, 80);
imagedestroy($image);

header指定をjpegにして、イメージの中身を実際に出力して戻す所。