因為工作需求,研究了一下圖片中產生文字的程式,之前會動到圖片函式都是縮圖裁切,或是修改驗證碼才會動到。
這次是單獨為了產生文字圖片而需要使用的程式。
首先 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>簡單的解釋就是我將圖片直接 使用 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;問題來了,為何 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 裡面含有不少系統內建的文字。



