Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The problem is you are feeding imagemagick the output of a "line splitter" (<code>wordWrapAnnotation</code>), to which you are <code>utf8_decode</code>ing the text input. This is wrong for sure, if you are dealing with Chinese text. <a href="http://php.net/manual/en/function.utf8-decode.php" rel="nofollow noreferrer"><code>utf8_decode</code></a> can only deal with UTF-8 text that CAN be converted to ISO-8859-1 (the most common 8-bit extension of ASCII).</p> <p>Now, I hope that you text is <a href="http://en.wikipedia.org/wiki/UTF-8" rel="nofollow noreferrer">UTF-8</a> encoded. If it is not, you might be able to convert it like this:</p> <pre><code>$text = mb_convert_encoding($text, 'UTF-8', 'BIG-5'); </code></pre> <p>or like this</p> <pre><code>$text = mb_convert_encoding($text, 'UTF-8', 'GB18030'); // only PHP &gt;= 5.4.0 </code></pre> <p>(in your code <code>$text</code> is rather <code>$text1</code> and <code>$text2</code>).</p> <p>Then there are (at least) two things to fix in your code:</p> <ol> <li>pass the text "as is" (without <code>utf8_decode</code>) to <code>wordWrapAnnotation</code>,</li> <li>change the argument of <code>setTextEncoding</code> from <code>"utf-8"</code> to <code>"UTF-8"</code> as per <a href="http://www.php.net/manual/en/imagickdraw.settextencoding.php" rel="nofollow noreferrer">specs</a></li> </ol> <p>I hope that all variables in your code are initialized in some missing part of it. With the two changes above (the second one might not be necessary, but you never know...), and with the missing parts in place, I see no reason why your code should not work, unless your TTF file is broken or the <code>Imagick</code> library is broken (<code>imagemagick</code>, on which <code>Imagick</code> is based, is a great library, so I consider this last possibility rather unlikely).</p> <p><strong>EDIT:</strong></p> <p>Following your request, I update my answer with</p> <p>a) the fact that setting <code>mb_internal_encoding('utf-8')</code> is very important for the solution, as you say in your <a href="https://stackoverflow.com/questions/11101544/how-to-use-imagick-annotateimage-for-chinese-text/11219404#11219404">answer</a>, and</p> <p>b) my proposal for a better line splitter, that works acceptably for western languages and for Chinese, and that is probably a good starting point for other languages using Han logograms (Japanese kanji and Korean hanja):</p> <pre><code>function wordWrapAnnotation(&amp;$image, &amp;$draw, $text, $maxWidth) { $regex = '/( |(?=\p{Han})(?&lt;!\p{Pi})(?&lt;!\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-&gt;queryFontMetrics($draw, $line); if ($metrics['textWidth'] &gt; $maxWidth) { if ($goodLine != '') { $linesArr[] = $goodLine; } $goodLine = $str; } else { $goodLine = $line; } if ($metrics['textHeight'] &gt; $lineHeight) { $lineHeight = $metrics['textHeight']; } } } if ($goodLine != '') { $linesArr[] = $goodLine; } return array($linesArr, $lineHeight); } </code></pre> <p>In words: the input is first cleaned up by replacing all runs of whitespace, including newlines, with a single space, except for leading and trailing whitespace, which is removed. Then it is split either at spaces, or right before Han characters not preceded by "leading" characters (like opening parentheses or opening quotes), or right before "leading" characters. Lines are assembled in order not to be rendered in more than <code>$maxWidth</code> pixels horizontally, except when this is not possible by the splitting rules (in which case the final rendering will probably overflow). A modification in order to force splitting in overflow cases is not difficult. Note that, e.g., Chinese punctuation is not classified as Han in Unicode, so that, except for "leading" punctuation, no linebreak can be inserted before it by the algorithm.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload