12

PHP 関数 imagettftext() を使用して、テキストを GIF 画像に変換しています。変換中のテキストに、日本語を含む Unicode 文字が含まれています。ローカル マシン (Ubuntu 7.10) ではすべて正常に動作しますが、Web ホスト サーバーでは日本語の文字が壊れています。違いの原因は何ですか?すべてを 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); 
4

5 に答える 5

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

関数 imagettftext() が名前付きエンティティを受け入れないことを除いて、文字列を HTML エンティティに変換すると機能します。例えば、

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

大丈夫ですが、

&ccedil;

ではありません。ISO-8859-1 に戻すと、名前付きエンティティが文字に戻されますが、2 つ目の問題があります。imagettftext() は、値が 127 を超える文字をサポートしていません。最後の for ループは、これらの文字を 16 進数でエンコードします。このソリューションは、私が使用しているテキスト (日本語、中国語、およびポルトガル語のアクセント付きラテン文字を含む) で機能していますが、すべての場合に機能するかどうかは 100% 保証されていません。

私のサーバーでは imagettftext() が実際には UTF-8 文字列を受け入れないため、これらすべての体操が必要です。

于 2008-10-14T16:02:47.710 に答える
12

画像内のテキストをレンダリングして出力するスクリプトでも同じ問題が発生しています。問題は、ブラウザーが異なるため(または、コードの難易度/パラノイア、どちらを考えても)、$_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これにより、すべての文字(マルチバイトUnicode文字を含む)をHTML数字エンティティ「&#65;」に変更するだけで、#127を超える文字を処理できないという問題が解決されます。「A」の場合、「&#66;」「B」などの場合-マニュアルページでサポートされていると主張しています。

于 2009-12-24T02:23:40.370 に答える
4

私も同じ問題を抱えていました。フォントを otf から ttf に変換すると役立ちました。FontForge (標準リポジトリで利用可能) を使用して変換できます。

于 2010-10-13T08:54:56.627 に答える
0

私の主な疑いは、レンダリングに使用しているフォントです。

http://fr3.php.net/imagettftextによると、php で使用される GD ライブラリのバージョンが異なると、異なる動作を示す場合があります。

  • ローカル マシンの GD バージョン: 2.0 以降
  • ウェブホスト サーバーの GD バージョン: バンドル (2.0.34 互換)

編集: 別のアイデア:$text = '日本語';本番サーバーにこのように実際に保存されていることを確認できますか? スクリプトにエンコードの問題がある可能性があります。

次の編集: BKB は既にそれを提案しました。したがって、これが原因である場合: 彼は最初に答えました;-)

于 2008-10-13T15:48:50.953 に答える
-1

その特定のフォント ファイルはプロダクション マシンに存在しますか? FTP を使用してファイルをアップロードする場合、バイナリ エンコーディングを使用していますか?

于 2008-10-13T17:10:59.710 に答える