PHP function imagettftext() and unicode

匆匆过客 提交于 2019-11-27 04:26:25
user27478

Here's the solution that finally worked for me:

$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;
    }
}

Converting the string to HTML entities works except that the function imagettftext() doesn't accept named entities. For example,

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

is OK, but

&ccedil;

is not. Converting back to ISO-8859-1, converts the named entities back to characters, but there is a second problem. imagettftext() doesn't support characters with a value greater than >127. The final for-loop encodes these characters in hexadecimal. This solution is working for me with the text that I am using (includes Japanese, Chinese and accented latin characters for Portuguese), but I'm not 100% sure it will work in all cases.

All of these gymnastics are needed because imagettftext() doesn't really accept UTF-8 strings on my server.

I have been having the same problem with a script that will render text in an image and output it. Problem was, that due to different browsers (or code hardiness/paranoia, whichever way you want to think of it), I had no way of knowing what encoding was being put inside the $_GET array.

Here is how I solved the problem.

$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');

This solves any problem with imagettftext not being able to handle characters above #127 by simply changing ALL the characters (including multibyte Unicode characters) into their HTML numeric character entity—"&#65;" for "A", "&#66;" for "B", etc.—which the manual page claims support for.

I had the same problem. Converting font from otf to ttf helped. You can use FontForge (available in standard repository) to convert.

My prime suspect is the font you are using for rendering.

According to http://fr3.php.net/imagettftext, different versions of the GD library used by php can show different behaviour.

  • GD Version on your local machine: 2.0 or higher
  • GD Version on your webhost server: bundled (2.0.34 compatible)

Edit: Another idea: can you verify that $text = '日本語'; is really saved like this on your production server? Maybe there is an encoding problem with your script.

Next edit: BKB already proposed that. So in case this is the cause: he was first with the answer ;-)

Does that particular font file exist on your production machine? If using FTP to upload your files, are you using binary encoding?

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!