初めまして。PHP(とガンダム)を勉強中の、エンジニアの庄子です。
PHPのGDライブラリを使っていて、文字を右寄せ出力する方法で少し悩みましたので、ブログネタにしてご紹介します。
テスト環境
・MAMP(php 5.5.10)
・chrome
・IPAフォントファイル
やりたいこと
下図のように、画像に複数行の任意の文字列を出力したい場合に、右寄せで揃えて出力したい。
つまり、こうなってしまうのを・・・
こうしたい!
対応方法
まず左寄せソースは下記のような感じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?PHP // 画像の新規作成 $image = imagecreatetruecolor(500, 300); // フォントサイズ $fsize = 50; // フォント角度 $fangle = 0; // フォントカラー $fcolor = imagecolorallocate($image, 255, 255, 255); // 使用フォント $fpath = "./ipagp.ttf"; // X座標マージン $margin = 10; // 文字出力 $textList = array("連邦の", "モビルスーツは", "化け物か"); for ($i = 0; $i < count($textList); $i++) { // 画像の出力位置を計算 $px = $margin; imagettftext($image, $fsize, $fangle, $px, 75 + 100 * $i, $fcolor, $fpath, $textList[$i]); } // 画像表示 header("Content-Type: image/png"); imagepng($image); // 後始末 imagedestroy($image); ?> |
残念ながら文字出力関数のimagettftextには、右寄せのオプションはありません。
そのため、
1. あらかじめ出力する文字列の長さを計算しておく
2. 右寄せで揃えたい位置から、計算した長さを引いたX座標に文字を出力
とする必要があります。
右寄せに対応したソースは下記になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<?PHP // 画像の新規作成 $image = imagecreatetruecolor(500, 300); // フォントサイズ $fsize = 50; // フォント角度 $fangle = 0; // フォントカラー $fcolor = imagecolorallocate($image, 255, 255, 255); // 使用フォント $fpath = "./ipagp.ttf"; // X座標マージン $margin = 10; // 文字出力 $textList = array("連邦の", "モビルスーツは", "化け物か"); for ($i = 0; $i < count($textList); $i++) { // 右寄せ $dim = imagettfbbox($fsize, $fangle, $fpath, $textList[$i]); // 幅を計算 $textWidth = $dim[4] - $dim[6]; // 画像の出力位置を計算 $px = 500 - $textWidth - $margin; imagettftext($image, $fsize, $fangle, $px, 75 + 100 * $i, $fcolor, $fpath, $textList[$i]); } // 画像表示 header("Content-Type: image/png"); imagepng($image); // 後始末 imagedestroy($image); ?> |
1.の文字列の長さは、imagettfbbox関数で求めることができます。
戻り値がテキスト出力時の左下、右下、右上、左上のそれぞれのX座標とY座標が配列で取得できるので、その値から幅を計算しています。
プロポーショナルフォントの場合、上記対応を行っても若干ずれているように見えてしまうため、出力する文字によって若干調整する必要があるかもしれません。
以上になります。
C/C++で育ってきた私としては、PHPの構文はスッと頭に入るので好きです。
今後もPHP(とガンダム)のお勉強がんばります!