imagettftextとimagettfbboxのフォントの中央合わせ【phpの画像と文字の合成】

少しははまったのでPHPの覚書です。

目次

phpの画像と文字の合成

画像生成する方法としてはGoとImageMagickの2つがありそうです。

違いは次のとおりです。

  • 簡単なタイトル画像生成ならGD
  • 複雑な画像合成・変換が必要ならImageMagick

今回、アイキャッチ画像を生成するだけなのでそこまで難しくはなさそうなのでGoにしましょうかね。

ただ、お使いのレンタルサーバーが対応しているのか否かという問題もあります。そのあたりから検討となりそうですね。

media_handle_sideload

media_handle_sideloadは年月のフォルダに勝手に振り分けられてしまうようですね…。個人的にあまりよろしくない…。

// アイキャッチ画像の設定
$attachment_id = media_handle_sideload(array(
    'name' => 'titleimage-' . $post_id . '.png',
    'type' => 'image/png',
    'tmp_name' => $file_path,
    'error' => 0,
    'size' => filesize($file_path),
), $post_id);
set_post_thumbnail($post_id, $attachment_id);

imagettftextとimagettfbboxのフォントの中央合わせ

画像にフォントを描画したのち、フォントを中央合わせしたくなる場合があります。

この場合、imagettftextとimagettfbboxを使うと便利です。

少しはまったポイントは、imagettfbboxでYの高さを取得したのですが、フォントサイズに行間を追加したものと高さが違うのです。

imagettfbboxでYの高さを取得した値を使って行間をだすようにしました。

    $text_width = abs($text_box[2] - $text_box[0]);
    $total_text_height = abs($text_box[1] - $text_box[7]);

    $num_lines = count($lines);
    $single_line_height = $total_text_height / $num_lines;

中央合わせの関数の戻り値です。この行間を使うようにしたらうまくいきました。

return array($text_x, $text_y, $single_line_height);

imagettfbboxの仕様

ざっくり調査です。

  1. 基本的な動作: imagettfbbox は、指定されたテキストを描画した場合の境界ボックス(bounding box)を計算します。この境界ボックスは、テキストが占める実際の領域を表します。
  2. 返される値: 関数は8つの要素を持つ配列を返します。これらは境界ボックスの4つの角の座標を表します。
    • 高さの計算に使用される主な値:
      • $bbox[1]: 左下のY座標
      • $bbox[7]: 左上のY座標
  3. 高さの計算方法: 実際の高さ = abs($bbox[1] – $bbox[7])
  4. 含まれる要素: 計算される高さには以下の要素が含まれます:
    • フォントのアセンダー(文字の上部が基準線より上に出る部分)
    • フォントのディセンダー(文字の下部が基準線より下に出る部分)
    • フォントのリーディング(内蔵された行間)
  5. フォントサイズとの関係: 実際の高さは通常、指定されたフォントサイズよりも大きくなります。これは、アセンダーとディセンダーが含まれるためです。
  6. 行間との関係:
    • 単一行のテキストの場合、指定された行間は高さ計算に影響しません。
    • 複数行のテキストの場合、PHP 8.0以降では imagettfbbox に ‘linespacing’ オプションを指定できます。これにより、行間を考慮した計算が可能になります。
  7. マージン: imagettfbbox 自体にマージンの概念はありません。計算される高さは純粋にフォントのメトリクスに基づいています。
  8. フォント依存性: 計算される高さは使用するフォントに大きく依存します。同じポイントサイズでも、フォントによって実際の高さは異なる場合があります。
  9. 特殊なケース:
    • 一部のフォントでは、文字によってはバウンディングボックスが予想外に大きくなることがあります(例:アクセント記号付きの文字)。
    • 複数行のテキストでは、各行の最大の高さが全体の高さとなります。

結論: imagettfbbox で計算される高さは、単純なフォントサイズ+行間ではありません。これはフォントの実際のメトリクスに基づいた、より正確な高さです。この高さには、フォントのアセンダー、ディセンダー、および内蔵のリーディングが含まれますが、追加の行間は含まれません(PHP 8.0未満の場合)。

imagettftextとimagettfbboxで表示されない!

PHP8にしたら表示されないですね。7に戻したら表示されました。

あまり時間がなかったため、詳しく原因は調べていません。PHP7で使っています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次