PHP函数imagettftext()和unicode

PHP函数imagettftext()和unicode,php,unicode,gd,Php,Unicode,Gd,我正在使用PHP函数imagettftext()将文本转换为GIF图像。我正在转换的文本包含Unicode字符,包括日语。在我的本地机器(Ubuntu 7.10)上一切都很好,但在我的webhost服务器上,日文字符被弄乱了。是什么造成了这种差异?所有内容都应编码为UTF-8 webhost服务器上损坏的映像: 从本地计算机复制正确的映像: 从我的本地计算机复制phpinfo(): 从我的webhost服务器复制phpinfo(): 代码: 我最怀疑的是你用来渲染的字体 据介绍,php使

我正在使用PHP函数imagettftext()将文本转换为GIF图像。我正在转换的文本包含Unicode字符,包括日语。在我的本地机器(Ubuntu 7.10)上一切都很好,但在我的webhost服务器上,日文字符被弄乱了。是什么造成了这种差异?所有内容都应编码为UTF-8

webhost服务器上损坏的映像:

从本地计算机复制正确的映像:

从我的本地计算机复制phpinfo():

从我的webhost服务器复制phpinfo():

代码:


我最怀疑的是你用来渲染的字体

据介绍,php使用的GD库的不同版本可以显示不同的行为

  • 本地计算机上的GD版本: 2.0或以上
  • webhost服务器上的GD版本:捆绑(2.0.34兼容)
编辑: 另一个想法是:你能验证一下
$text=日本語';
是否真的像这样保存在生产服务器上?您的脚本可能存在编码问题


下一次编辑:BKB已经提出了。如果这是原因:他是第一个得到答案的;-)

生产机器上是否存在该特定字体文件?如果使用FTP上传文件,是否使用二进制编码?

以下是最终对我有效的解决方案:

$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;
    }
}
没关系,但是

&ccedil;
事实并非如此。转换回ISO-8859-1时,会将命名实体转换回字符,但还有第二个问题。imagettftext()不支持值大于127的字符。最后一个for循环以十六进制编码这些字符。这个解决方案适用于我正在使用的文本(包括日语、汉语和葡萄牙语的重音拉丁字符),但我不能100%确定它是否适用于所有情况


所有这些练习都是必需的,因为imagettftext()在我的服务器上并不真正接受UTF-8字符串。

我一直在使用一个脚本来呈现图像中的文本并输出它,这与此问题相同。问题是,由于不同的浏览器(或者代码抵抗力/偏执狂,不管你怎么想),我无法知道
$\u 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
无法处理127以上字符的任何问题,只需将所有字符(包括多字节Unicode字符)更改为HTML数字字符实体-“A;”表示“A”,表示“B”,等等,这些都是声明支持的。

我也有同样的问题。将字体从otf转换为ttf有帮助。您可以使用FontForge(在标准存储库中提供)进行转换。

为什么UTF-8>HTML entities>ISO-8859转换而不是简单的UTF-8>ISO-8859?+1正如deceze提到的,我可能会使用
iconv('UTF-8','ISO-8859-1',$text)
而不是实体方法,但除此之外,转换为十六进制表示法是一条路要走!谢谢你的提示!而UTF-8到ISO-8859-1有一个功能,它的utf8_decode@deceze因为它不是关于字符集转换的,对我来说也很有用。我正试图打印TM字符。虽然我试过的所有字体中都有字符,但只在某些字体中起作用。这条评论为我节省了很多调试时间。如果你不想使用FontForge,一个提示:显然这里是最好的解决方案!这是一个评论,不是对问题的回答,因此是否决票。
&ccedil;
$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');