imagettftext() の中央寄せ、右寄せ
imagettftext()
には中央寄せや右寄せなどの位置合わせの機能がないため、中央寄せや右寄せをするには imagettfbbox()
で取得できる座標を利用して自力で調整する必要があります。
imagettfbox() の座標
imagettfbbox()
で取得できる座標の配列 (0~7の8つの座標) は下記のような意味になっています。
imagettftext() で指定する x, y の原点は左下で imagettfbbox() もその前提になっているため、imagettfbbox() の [0], [1], [3] が 0 に近く、[5], [7] が負の値になっていることがよくあります。
位置の計算
上記の imagettfbox()
の座標からテキストの幅・高さを算出して、指定エリアの座標をもとに位置を算出します。
下記は angle が 0 の場合の例です。また、矩形座標の原点は左上を前提としています。
- テキスト幅 = imagettfbbox()[2 または 4] - imagettfbbox()[0 または 6]
- テキスト高さ = imagettfbbox()[1 または 3] - imagettfbbox()[5 または 7]
- 中央寄せ
- x = 矩形座標x1 + ((矩形座標x2 - 矩形座標x1 - テキスト幅) / 2)
- y = 矩形座標y1 + ((矩形座標y2 - 矩形座標y1 - テキスト高さ) / 2) - imagettfbbox()[5 または 7];
- 右寄せ
- x = 矩形座標x2 - テキスト幅
サンプルコード (9点対応)
左上、上、右上、左、中央、右、左下、下、右下 の 9点に対応した例です。 フォントにより (日本語など) 少しずれる場合があり、その場合は個別に調整が必要になるかもしれません。
<?php
// 位置定数
define('IMAGETTFTEXT_ALIGN_TOPLEFT' , 1); // 左上
define('IMAGETTFTEXT_ALIGN_TOPCENTER' , 2); // 上
define('IMAGETTFTEXT_ALIGN_TOPRIGHT' , 3); // 右上
define('IMAGETTFTEXT_ALIGN_MIDDLELEFT' , 4); // 左
define('IMAGETTFTEXT_ALIGN_MIDDLECENTER', 5); // 中央
define('IMAGETTFTEXT_ALIGN_MIDDLERIGHT' , 6); // 右
define('IMAGETTFTEXT_ALIGN_BOTTOMLEFT' , 7); // 左下
define('IMAGETTFTEXT_ALIGN_BOTTOMCENTER', 8); // 下
define('IMAGETTFTEXT_ALIGN_BOTTOMRIGHT' , 9); // 右下
/**
* TrueType フォントを使用して、指定されたエリア(矩形座標)の範囲にテキストを書き込みます。
* ($angle は基本的に 0 を想定しています。細かい挙動の調整等はしていません)
*
* @param resource $image 画像リソース (imagettftext() と同じ)
* @param float $size ポイント数単位のフォントサイズ (同上)
* @param float $angle 度で表される角度 (同上)
* @param int $x1 矩形の左上の X 座標 (imagettftext() は左下のため注意してください)
* @param int $y1 矩形の左上の Y 座標 (同上)
* @param int $x2 矩形の右下の X 座標
* @param int $y2 矩形の右下の Y 座標
* @param int $color カラーインデックス (imagettftext() と同じ)
* @param string $fontfile 使用したい TrueType フォントへのパス (同上)
* @param string $text テキスト文字列 (同上)
* @param int $pos
* @return void
*/
function imagettftext_align($image, $size, $angle, $x1, $y1, $x2, $y2, $color, $fontfile, $text, $pos = IMAGETTFTEXT_ALIGN_MIDDLECENTER) {
$box = imageftbbox($size, $angle, $fontfile, $text); // テキストのバウンディングボックス
$textWidth = $box[4] - $box[0]; // テキスト幅
$textHeight = $box[1] - $box[5]; // テキスト高さ
// Y 座標算出
switch ($pos) {
// 上
case IMAGETTFTEXT_ALIGN_TOPLEFT:
case IMAGETTFTEXT_ALIGN_TOPCENTER:
case IMAGETTFTEXT_ALIGN_TOPRIGHT:
$y = $y1 - $box[5];
break;
// 中央
case IMAGETTFTEXT_ALIGN_MIDDLELEFT:
case IMAGETTFTEXT_ALIGN_MIDDLECENTER:
case IMAGETTFTEXT_ALIGN_MIDDLERIGHT:
$y = $y1 + (($y2 - $y1 - $textHeight) / 2) - $box[5];
break;
// 下
case IMAGETTFTEXT_ALIGN_BOTTOMLEFT:
case IMAGETTFTEXT_ALIGN_BOTTOMCENTER:
case IMAGETTFTEXT_ALIGN_BOTTOMRIGHT:
$y = $y2 - $textHeight - $box[5];
break;
}
// X 座標算出
switch ($pos) {
// 左
case IMAGETTFTEXT_ALIGN_TOPLEFT:
case IMAGETTFTEXT_ALIGN_MIDDLELEFT:
case IMAGETTFTEXT_ALIGN_BOTTOMLEFT:
$x = $x1;
break;
// 中央
case IMAGETTFTEXT_ALIGN_TOPCENTER:
case IMAGETTFTEXT_ALIGN_MIDDLECENTER:
case IMAGETTFTEXT_ALIGN_BOTTOMCENTER:
$x = $x1 + (($x2 - $x1 - $textWidth) / 2);
break;
// 右
case IMAGETTFTEXT_ALIGN_TOPRIGHT:
case IMAGETTFTEXT_ALIGN_MIDDLERIGHT:
case IMAGETTFTEXT_ALIGN_BOTTOMRIGHT:
$x = $x2 - $textWidth;
break;
}
imagettftext($image, $size, $angle, $x, $y, $color, $fontfile, $text);
}
// -- テスト --
$width = 600; // 画像幅
$height = 300; // 画像高さ
$x1 = 0; // テキスト矩形 X 座標
$y1 = 0; // テキスト矩形 Y 座標
$x2 = $width - 1; // テキスト矩形 X 座標 2
$y2 = $height - 1; // テキスト矩形 Y 座標 2
$size = 30; // フォントサイズ
$text = 'ABCDE'; // テキスト
$fontfile = 'GenShinGothic-Normal.ttf'; // フォント (例では http://jikasei.me/font/genshin/ の源真ゴシック)
$image = imagecreatetruecolor($width, $height); // 画像リソース
$color = imagecolorallocate($image, 0x00, 0x00, 0x00); // 文字色
$back = imagecolorallocate($image, 0xff, 0xff, 0xff); // 背景色
imagefilledrectangle($image, 0, 0, $width, $height, $back); // 背景描画
imagerectangle($image, $x1, $y1, $x2, $y2, $color); // ガイド線描画
imagerectangle($image, $x1, $y1 / 2, $x2, $y2 / 2, $color); // 同上
imagerectangle($image, $x1 / 2, $y1, $x2 / 2, $y2, $color); // 同上
// 文字描画
imagettftext_align($image, $size, 0, $x1, $y1, $x2, $y2, $color, $fontfile, $text, IMAGETTFTEXT_ALIGN_TOPLEFT); // 左上
imagettftext_align($image, $size, 0, $x1, $y1, $x2, $y2, $color, $fontfile, $text, IMAGETTFTEXT_ALIGN_TOPCENTER); // 上
imagettftext_align($image, $size, 0, $x1, $y1, $x2, $y2, $color, $fontfile, $text, IMAGETTFTEXT_ALIGN_TOPRIGHT); // 右上
imagettftext_align($image, $size, 0, $x1, $y1, $x2, $y2, $color, $fontfile, $text, IMAGETTFTEXT_ALIGN_MIDDLELEFT); // 左
imagettftext_align($image, $size, 0, $x1, $y1, $x2, $y2, $color, $fontfile, $text, IMAGETTFTEXT_ALIGN_MIDDLECENTER); // 中央
imagettftext_align($image, $size, 0, $x1, $y1, $x2, $y2, $color, $fontfile, $text, IMAGETTFTEXT_ALIGN_MIDDLERIGHT); // 右
imagettftext_align($image, $size, 0, $x1, $y1, $x2, $y2, $color, $fontfile, $text, IMAGETTFTEXT_ALIGN_BOTTOMLEFT); // 左下
imagettftext_align($image, $size, 0, $x1, $y1, $x2, $y2, $color, $fontfile, $text, IMAGETTFTEXT_ALIGN_BOTTOMCENTER); // 下
imagettftext_align($image, $size, 0, $x1, $y1, $x2, $y2, $color, $fontfile, $text, IMAGETTFTEXT_ALIGN_BOTTOMRIGHT); // 右下
// 画像出力
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);