PHP-функция imagettftext() и unicode
Я использую функцию PHP imagettftext() для преобразования текста в GIF-образ. Текст, который я конвертирую, имеет символы Юникода, включая японский. Все работает нормально на моей локальной машине (Ubuntu 7.10), но на моем сервере веб-хостинга японские персонажи искалечены. Что может быть причиной разницы? Все должно быть закодировано как UTF-8.
Сломанное изображение на сервере веб-хостинга:
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);
Ответы
Ответ 1
Вот решение, которое, наконец, помогло мне:
$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() не принимает именованные объекты. Например,
日本語
в порядке, но
ç
нет. Возвращаясь к ISO-8859-1, преобразует именованные объекты обратно в символы, но есть вторая проблема. imagettftext() не поддерживает символы со значением больше > 127. Финал for-loop кодирует эти символы в шестнадцатеричном формате. Это решение работает для меня с текстом, который я использую (включает в себя японские, китайские и акцентированные латинские символы для португальцев), но я не уверен на 100%, что он будет работать во всех случаях.
Вся эта гимнастика необходима, потому что imagettftext() на самом деле не принимает строки UTF-8 на моем сервере.
Ответ 2
У меня была такая же проблема с script, которая будет отображать текст в изображении и выводить его. Проблема заключалась в том, что из-за разных браузеров (или выносливости кода/паранойи, какой бы способ вы ни думали об этом) я не знал, что кодировка помещается внутри массива $_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 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, просто изменяя ВСЕ символы (включая многобайтовые символы Юникода) в их числовой символ символа HTML — "& # 65;" для "A", "& # 66;" для "B" и т.д., на которую ссылается справочная страница.
Ответ 3
У меня была та же проблема. Преобразование шрифта из otf в ttf помогло. Вы можете использовать FontForge (доступный в стандартном репозитории) для преобразования.
Ответ 4
Мой главный подозреваемый - это шрифт, который вы используете для рендеринга.
В соответствии с http://fr3.php.net/imagettftext различные версии библиотеки GD, используемые php, могут показывать различное поведение.
- Версия GD на вашем локальном компьютере:
2.0 или выше
- Версия GD на сервере веб-хостинга: в комплекте (совместим с 2.0.34)
Изменить:
Другая идея: можете ли вы проверить, что $text = '日本語';
действительно сохраняется на вашем рабочем сервере, как это происходит на вашем рабочем сервере? Возможно, есть проблема с кодировкой с вашим script.
Далее править: BKB уже предложил это. Итак, в случае, если это причина: он сначала ответил: -)
Ответ 5
У меня возникла та же проблема, и я нашел простое решение из справочника php PHP ImageTttfText frunch:
Чтобы скопировать необходимый файл шрифта, например (arial.ttf), в тот же каталог с вашим php файлом:
(c:\wamp\www\mysite\mypage.php)
(c:\wamp\www\mysite\arial.ttf)
где mysite: это ваш каталог веб-сайта
но попробуйте изменить переменную $font как
$font = 'arial.ttf';
Ответ 6
Этот файл шрифта существует на вашей производственной машине? Если вы используете FTP для загрузки ваших файлов, вы используете двоичное кодирование?