2008-10-13 113 views
10

我正在使用PHP函數imagettftext()將文本轉換爲GIF圖像。我正在轉換的文本包含Unicode字符,包括日語。一切工作正常我的本地機器上(Ubuntu 7.10),但在我的虛擬主機服務器上,日文字符被打亂。什麼可能導致差異?一切都應該編碼爲UTF-8。PHP函數imagettftext()和unicode

虛擬主機提供商的服務器上

破碎的形象:從我的本地機器上正確的圖像的 http://www.ibeni.net/flashcards/imagetest.php

複製: http://www.ibeni.net/flashcards/imagetest.php.gif

從我的本地機器的phpinfo()的複製: http://www.ibeni.net/flashcards/phpinfo.php.html

的phpinfo複製()從我的虛擬主機服務器: http://example5.nfshost.com/phpinfo

代碼:

mb_language('uni'); 
mb_internal_encoding('UTF-8'); 

header('Content-type: image/gif'); 

$text = '日本語'; 
$font = './Cyberbit.ttf'; 

// Create the image 
$im = imagecreatetruecolor(160, 160); 
$white = imagecolorallocate($im, 255, 255, 255); 
$black = imagecolorallocate($im, 0, 0, 0); 

// Create some colors 
imagefilledrectangle($im, 0, 0, 159, 159, $white); 

// Add the text 
imagettftext($im, 12, 0, 20, 20, $black, $font, $text); 
imagegif($im); 
imagedestroy($im); 

回答

13

下面是最終爲我工作的解決方案:

$text = "你好"; 
// Convert UTF-8 string to HTML entities 
$text = mb_convert_encoding($text, 'HTML-ENTITIES',"UTF-8"); 
// Convert HTML entities into ISO-8859-1 
$text = html_entity_decode($text,ENT_NOQUOTES, "ISO-8859-1"); 
// Convert characters > 127 into their hexidecimal equivalents 
$out = ""; 
for($i = 0; $i < strlen($text); $i++) { 
    $letter = $text[$i]; 
    $num = ord($letter); 
    if($num>127) { 
     $out .= "&#$num;"; 
    } else { 
     $out .= $letter; 
    } 
} 

轉換字符串爲HTML實體作品除了功能imagettftext()不接受命名實體。例如,

&#26085;&#26412;&#35486; 

是確定的,但

&ccedil; 

不是。轉換回ISO-8859-1,將命名實體轉換回字符,但還有第二個問題。 imagettftext()不支持值大於> 127的字符。最終的for-loop以十六進制編碼這些字符。這個解決方案適用於我正在使用的文本(包括日文,中文和葡萄牙語重音拉丁文字符),但我不能100%確定它可以在任何情況下使用。

所有這些體操都是需要的,因爲imagettftext()並不真正接受我的服務器上的UTF-8字符串。

+1

爲什麼UTF-8> HTML實體> ISO-8859轉換而不是簡單的UTF-8> ISO-8859? – deceze 2012-02-26 23:38:23

+0

+1就像上面提到的那樣,我可能會使用`iconv('UTF-8','ISO-8859-1',$ text)`而不是實體方法,但除了轉換爲** hex代表**是要走的路! Thx的小費! – Levit 2014-08-31 14:12:22

+0

確認沒有與阿拉伯語 – AbiusX 2015-02-07 22:34:12

0

我的主要嫌疑犯是您用於渲染的字體。

根據http://fr3.php.net/imagettftext,php使用的不同版本的GD庫可以顯示不同的行爲。

  • GD版本在本地計算機上:您的虛擬主機提供商的服務器上 2.0或更高版本
  • GD版本:捆綁(2.0.34兼容)

編輯: 另一個想法:你可以驗證$text = '日本語';是否真的在您的生產服務器上保存了?也許你的腳本存在編碼問題。

下一個編輯: BKB已經提出。因此,如果這是原因:他是第一個答案;-)

-1

您的生產機器上是否存在特定的字體文件?如果使用FTP上傳文件,您是否使用二進制編碼?

+1

這是一個評論,而不是問題的答案,因此downvote。 – mirabilos 2016-11-03 13:02:10

11

我一直有一個腳本,將呈現圖像中的文本並輸出它的問題。問題在於,由於不同的瀏覽器(或代碼強度/偏執狂,無論您想怎麼想),我無法知道$_GET陣列中正在放入什麼編碼。

下面是我如何解決這個問題。

$item_text = $_GET['text']; 

# detect if the string was passed in as unicode 
$text_encoding = mb_detect_encoding($item_text, 'UTF-8, ISO-8859-1'); 
# make sure it's in unicode 
if ($text_encoding != 'UTF-8') { 
    $item_text = mb_convert_encoding($item_text, 'UTF-8', $text_encoding); 
} 

# html numerically-escape everything (&#[dec];) 
$item_text = mb_encode_numericentity($item_text, 
    array (0x0, 0xffff, 0, 0xffff), 'UTF-8'); 

這解決任何問題imagettftext不能通過簡單地所有字符(多字節包括Unicode字符)改變到他們的HTML數字字符實體能夠處理上述#127個字符—「&#65;」爲「A」,「&#66;」 「B」等—其中manual page聲稱支持。

3

我有同樣的問題。轉換字體從otf到ttf幫助。您可以使用FontForge(標準存儲庫中提供)進行轉換。

0

我面臨同樣的問題,我發現從PHP參考PHP ImageTttfText frunction一個簡單的解決方案:

那你在同一目錄與你的PHP文件複製所需的字體文件,例如(ARIAL.TTF):

(c:\wamp\www\mysite\mypage.php) 
(c:\wamp\www\mysite\arial.ttf) 

其中mysite的:是你的網站目錄

但試圖改變$字體變量是

$font = 'arial.ttf';