发布于 2012-06-27 04:28:17
完全解决办法如下:
https://gist.github.com/2971092/232adc3ebfc4b45f0e6e8bb5934308d9051450a4
主要想法:
必须在表单和处理页上设置html字符集和内部编码。
header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding('utf-8');这些行必须位于php文件的最上层。
使用此函数确定文本是否为中文,并使用正确的字体文件。
function isThisChineseText($text) {
return preg_match("/\p{Han}+/u", $text);
}有关更多详细信息,请访问https://stackoverflow.com/a/11219301/80353
在ImagickDraw对象中正确设置TextEncoding
$draw = new ImagickDraw();
// set utf 8 format
$draw->setTextEncoding('UTF-8');注意大写的UTF。THis在他的回答:https://stackoverflow.com/a/11207521/80353中得到了沃尔特·特罗斯的帮助。
使用preg_match_all爆炸英语单词,中文单词和空格
// separate the text by chinese characters or words or spaces
preg_match_all('/([\w]+)|(.)/u', $text, $matches);
$words = $matches[0];受到这个答案的启发,https://stackoverflow.com/a/4113903/80353
同样适用于英文文本
发布于 2012-06-26 12:38:52
问题是,您正在输入“分行器”(wordWrapAnnotation)的输出图像,您正在对其输入文本进行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和$text2)。
然后(至少)在代码中有两件事情需要修复:
utf8_decode)传递给wordWrapAnnotation,setTextEncoding的参数从"utf-8"更改为"UTF-8" (按规格 )我希望您的代码中的所有变量都在它缺少的部分中初始化。有了上述两个更改(第二个更改可能没有必要,但您永远不知道.),在缺少部分的情况下,我没有理由认为您的代码不应该工作,除非您的TTF文件被破坏或Imagick库被破坏(基于imagemagick的Imagick是一个很好的库,所以我认为这最后的可能性不大可能)。
编辑:
应您的要求,我将我的答复更新为
设置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中不被归类为汉标点符号,因此,除“引导”标点符号外,算法不能在其前面插入任何行符。
发布于 2012-06-22 13:38:28
恐怕你必须选择一个能够支持中文编码点的TTF。这方面有很多来源,这里有两个:
ChineseTraditional.html
http://wildboar.net/multilingual/asian/chinese/language/fonts/unicode/non-microsoft/non-microsoft.html
https://stackoverflow.com/questions/11101544
复制相似问题