PHP функция imagettftext () и Unicode - PullRequest
11 голосов
/ 13 октября 2008

Я использую функцию 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); 

Ответы [ 5 ]

13 голосов
/ 14 октября 2008

Вот решение, которое наконец-то сработало для меня:

$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 кодирует эти символы в шестнадцатеричном формате. Это решение работает для меня с текстом, который я использую (включает японский, китайский и латинский символы с акцентированным знаком для португальского), но я не уверен на 100%, что это будет работать во всех случаях.

Все эти гимнастические упражнения необходимы, потому что imagettftext () не принимает строки UTF-8 на моем сервере.

12 голосов
/ 24 декабря 2009

У меня возникла та же проблема со скриптом, который будет отображать текст на изображении и выводить его. Проблема заключалась в том, что из-за разных браузеров (или сложности кода / паранойи, в зависимости от того, как вы хотите об этом думать), у меня не было возможности узнать, какая кодировка помещается в массив $_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, просто заменяя ВСЕ символы (включая многобайтовые символы Юникода) на их числовые символы HTML - "A" для "A", "B" для "B" и т. д. - на которые заявлена ​​поддержка справочной страницы .

3 голосов
/ 13 октября 2010

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

0 голосов
/ 13 октября 2008

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

0 голосов
/ 13 октября 2008

Мой главный подозреваемый - это шрифт, который вы используете для рендеринга.

Согласно http://fr3.php.net/imagettftext, различные версии библиотеки GD, используемые php, могут демонстрировать различное поведение.

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

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

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

...