問題は、テキスト入力を行っている「ラインスプリッター」( wordWrapAnnotation
)の出力をimagemagickに供給していることです。utf8_decode
中国語のテキストを扱っている場合、これは確かに間違っています。utf8_decode
ISO-8859-1 (ASCII の最も一般的な 8 ビット拡張) に変換できる UTF-8 テキストのみを処理できます。
さて、あなたのテキストがUTF-8でエンコードされていることを願っています。そうでない場合は、次のように変換できます。
$text = mb_convert_encoding($text, 'UTF-8', 'BIG-5');
またはこのように
$text = mb_convert_encoding($text, 'UTF-8', 'GB18030'); // only PHP >= 5.4.0
(あなたのコード$text
ではむしろ$text1
and$text2
です)。
次に、コードで修正する必要がある (少なくとも) 2 つの点があります。
- テキストを「そのまま」(なしで
utf8_decode
) にwordWrapAnnotation
渡します。
- 仕様
に従って
setTextEncoding
fromの引数を"utf-8"
to に変更します"UTF-8"
コード内のすべての変数が、欠落している部分で初期化されることを願っています。上記の 2 つの変更 (2 番目の変更は必要ないかもしれませんが、わかりません...) と、欠落している部分があるため、TTF ファイルが壊れているか、Imagick
ライブラリが壊れています (imagemagick
にImagick
基づいている は優れたライブラリであるため、この最後の可能性はかなり低いと思います)。
編集:
あなたのリクエストに続いて、私は私の答えを次のように更新します
a)mb_internal_encoding('utf-8')
あなたの答えで言うように、設定はソリューションにとって非常に重要であるという事実、および
b) 西洋言語と中国語で問題なく機能する、より優れたライン スプリッターに関する私の提案です。これは、おそらく、漢語の表意文字 (日本語の漢字と韓国語の漢字) を使用する他の言語の出発点として適しています。
function wordWrapAnnotation(&$image, &$draw, $text, $maxWidth)
{
$regex = '/( |(?=\p{Han})(?<!\p{Pi})(?<!\p{Ps})|(?=\p{Pi})|(?=\p{Ps}))/u';
$cleanText = trim(preg_replace('/[\s\v]+/', ' ', $text));
$strArr = preg_split($regex, $cleanText, -1, PREG_SPLIT_DELIM_CAPTURE |
PREG_SPLIT_NO_EMPTY);
$linesArr = array();
$lineHeight = 0;
$goodLine = '';
$spacePending = false;
foreach ($strArr as $str) {
if ($str == ' ') {
$spacePending = true;
} else {
if ($spacePending) {
$spacePending = false;
$line = $goodLine.' '.$str;
} else {
$line = $goodLine.$str;
}
$metrics = $image->queryFontMetrics($draw, $line);
if ($metrics['textWidth'] > $maxWidth) {
if ($goodLine != '') {
$linesArr[] = $goodLine;
}
$goodLine = $str;
} else {
$goodLine = $line;
}
if ($metrics['textHeight'] > $lineHeight) {
$lineHeight = $metrics['textHeight'];
}
}
}
if ($goodLine != '') {
$linesArr[] = $goodLine;
}
return array($linesArr, $lineHeight);
}
つまり、改行を含む空白のすべての実行を単一のスペースに置き換えることにより、入力が最初にクリーンアップされます。ただし、先頭と末尾の空白は削除されます。次に、スペースで分割されるか、「先頭」文字 (開き括弧や開き引用符など) が先行しない漢字の直前、または「先頭」文字の直前で分割されます。ラインは、水平方向にピクセルを超えてレンダリングされないように組み立てられます$maxWidth
。ただし、分割規則によってこれが不可能な場合を除きます (この場合、最終的なレンダリングはおそらくオーバーフローします)。オーバーフローの場合に強制的に分割するための変更は難しくありません。たとえば、中国語の句読点は Unicode では漢語として分類されないため、「先頭の」句読点を除いて、