2008-10-13 116 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';