[PHP] 產生文字圖片,文字置中

by Mesak

因為工作需求,研究了一下圖片中產生文字的程式,之前會動到圖片函式都是縮圖裁切,或是修改驗證碼才會動到。

這次是單獨為了產生文字圖片而需要使用的程式。

首先 Google 一下 最簡單的生出圖片的方式就是利用GD來產生 :

<?php 
header("Content-type: image/png"); //設定圖檔格式
$im = @imagecreatetruecolor(80, 20) or die("無法建立圖片!"); //建立一張全彩圖
$text_color = imagecolorallocate($im, 255, 255, 255);  //設定文字顏色
imagestring($im, 2, 5, 2, "Hi! I'm Tad", $text_color);  //將字串加入圖片中
imagepng($im);  //產生圖片
imagedestroy($im);   //結束$im釋放記憶體 
?>

引用來源:[PHP]自動產生圖形 header image系列指令

來源裡面已經有一些解釋了,暫時就不多做註解了。

為了方便測試我將它變成一個頁面處理,以及增加一些變數好控制,修正一版如下:

<html>
	<body>
<?
$img = image();
echo '<img src="data:image/png;base64,' . $img . '" />';
function image()
{
    $width         = 120;
    $height        = 20;
    $x             = 5;
    $y             = 0;
    $im            = imagecreatetruecolor($width, $height);
    $text_color    = imagecolorallocate($im, 255, 255, 255);
    $word          = "Hello World";
    $font_size     = 5;
    imagestring($im, $font_size, $x, $y, $word, $text_color);
    ob_start();
    imagepng($im);
    $output = base64_encode(ob_get_clean());
    imagedestroy($im);
    return $output;
}
?>
</body>
</html>

出現結果如下圖:
php create image font text center

簡單的解釋就是我將圖片直接 使用 base64 輸出,整個畫面就是 HTML 直接輸出,文章之後的程式碼將只更新 function 內的程式嚕。

接著要產生這種文字圖片的重點就是要置中,稍為研究了一下置中,就是使用 imagefontwidth 與 imagefontheight 這兩個函式,取得單字元的大小,在重新計算字串的位置,結果如下:

    $width          = 300;
    $height         = 300;
    $im             = imagecreatetruecolor($width, $height);
    $text_color     = imagecolorallocate($im, 255, 255, 255);
    $word           = "Hello World";
    $font_size      = 5;
    $font_width     = imagefontwidth( $font_size ) * strlen( $word ) /2;
    $font_height    = imagefontheight( $font_size ) / 2;
    $x              = $width / 2 - $font_width;
    $y              = $height / 2 - $font_height;
    imagestring($im, $font_size, $x, $y, $word, $text_color);
    ob_start();
    imagepng($im);
    $output = base64_encode(ob_get_clean());
    imagedestroy($im);
    return $output;

輸出結果如下圖:
php create image font text center

問題來了,為何 imagestring 字元大小只能放大到 5 呢?

因為這個函式只有內建 latin2 encoding 編碼的 1 2 3 4 5 大小,如果需要再大的話需要使用 imageloadfont 來載入字型,imageloadfont 載入的字型又是 GDF 的格式,格式為點陣圖,大部分都不支援中文,現在都使用 向量字體了,如果想載入字型來操作的話,就必須使用 imagettftext 這個函式了,imagettftext  這個函式判斷字體的大小又不太一樣,所以最後修正版本如下:

    $width           = 300;
    $height          = 300;
    $use_font        = TRUE;
    $im              = imagecreatetruecolor($width, $height);
    $text_color      = imagecolorallocate($im, 255, 255, 255);
    $word            = "Hello World";
    $font_size       = 24;
    $font_path       = 'arial.ttf';
    $angle           = 0;
    if ($use_font    == FALSE)
    {
        $font_width      = imagefontwidth( $font_size ) * strlen( $word ) /2;
        $font_height     = imagefontheight( $font_size ) / 2;
    }else{
        $bbox            = imagettfbbox($font_size, $angle, $font_path, $word );
        $font_width      = $bbox[4] / 2;
        $font_height     = $bbox[5] / 2;
    }
    $x  = $width / 2 - $font_width;
    $y  = $height / 2 - $font_height;
    if ($use_font == FALSE)
        imagestring($im, $font_size, $x, $y, $word, $text_color);
    else
        imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, $word);
    
    ob_start();
    imagepng($im);
    $output = base64_encode(ob_get_clean());
    imagedestroy($im);
    return $output;

增加了 $use_font 的判斷是否要使用字型,字型長寬判斷使用 imagettfbbox 來判定,需要在同目錄放置 TTF 的文字檔案,Windows 的 Windows\Font 裡面含有不少系統內建的文字。

輸出結果如下圖:
php create image font text center

You may also like