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