2008-10-13 5 views
10

Я использую функцию PHP imagettftext() для преобразования текста в GIF-изображение. Текст, который я конвертирую, имеет символы Юникода, включая японский. Все работает нормально на моей локальной машине (Ubuntu 7.10), но на моем сервере веб-хостинга японские персонажи искалечены. Что может быть причиной разницы? Все должно быть закодировано как UTF-8.PHP function 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, различные версии библиотеки GD, используемые php, могут показывать различное поведение.

  • GD версии на локальном компьютере: 2,0 или выше
  • GD версии на веб-хостинга серверов: в комплекте (2.0.34 совместимый)

Edit: Еще одна идея: вы можете убедитесь, что $text = '日本語'; действительно сохранен на вашем сервере? Возможно, в вашем скрипте есть проблема с кодировкой.

Следующая редакция: BKB уже предложил это. Так что в случае, если это причина: он был первым с ответом ;-)

-1

Этот файл шрифта существует на вашей производственной машине? Если вы используете FTP для загрузки ваших файлов, используете ли вы двоичную кодировку?

+1

Это комментарий, а не ответ на вопрос, следовательно, нижний предел. – 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 не в состоянии обрабатывать символы выше # 127, просто меняя все символы (в том числе многобайтовых символов Unicode) в числовую сущность символов HTML — «& # 65;» для "A", "& # 66;" для «B» и т. д. —, который поддерживает manual page.

3

У меня была та же проблема. Преобразование шрифта из otf в ttf помогло. Вы можете использовать FontForge (доступный в стандартном репозитории) для преобразования.

0

я столкнулся с той же проблемой, и я нашел простое решение от референсной PHP PHP ImageTttfText frunction:

Что вы можете скопировать требуемый файл шрифта, например (arial.ttf) в той же директории с файлом PHP:

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

где MySite: ваш веб-сайт каталога

но попытаться изменить переменную $ шрифта, чтобы быть

$font = 'arial.ttf'; 

 Смежные вопросы

  • Нет связанных вопросов^_^