php – 如何使用imagick annotateImage中文文本?

前端之家收集整理的这篇文章主要介绍了php – 如何使用imagick annotateImage中文文本?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要使用中文文本注释图像,我现在正在使用Imagick库.

中文文本的一个例子是

这是中文

使用的中文字体文件this

文件最初名为华文黑体.ttf

它也可以在Mac OSX的/ Library / Font下找到

我已将其重命名为英语STHeiTi.ttf,可以更轻松地在PHP代码调用文件.

特别是the Imagick::annotateImage function

我也是using the answer from “How can I draw wrapped text using Imagick in PHP?”.

我使用它的原因是因为英语文本和应用程序需要注释英文和中文,但不能同时注释.

问题是,当我使用中文文本运行annotateImage时,我得到的注释看起来像罍

代码包括here

问题是你正在为imagemagick提供一个“行分割器”(wordWrapAnnotation)的输出,你可以对文本输入进行utf8_decodeing.如果您正在处理中文文本,这肯定是错误的. utf8_decode只能处理可以转换为ISO-8859-1(最常见的8位ASCII扩展名)的UTF-8文本.

现在,我希望你的文字UTF-8编码.如果不是,您可以像这样转换它:

$text = mb_convert_encoding($text,'UTF-8','BIG-5');

或者像这样

$text = mb_convert_encoding($text,'GB18030'); // only PHP >= 5.4.0

(在你的代码中,$text更像是$text1和$text2).

然后在您的代码中(至少)要修复两件事:

>将文本“按原样”(不带utf8_decode)传递给wordWrapAnnotation,
>将setTextEncoding的参数从“utf-8”更改为“UTF-8”
按照specs

我希望代码中的所有变量都在其中缺少的部分进行初始化.通过上面的两个更改(第二个可能没有必要,但你永远不知道……),并且缺少部分,我认为没有理由为什么你的代码不能工作,除非你的TTF文件被破坏或者Imagick库已经坏了(imagemagick,Imagick所基于的,是一个很棒的库,所以我认为最后一种可能性不太可能).

编辑:

根据您的要求,我更新了我的答案

a)设置mb_internal_encoding(‘utf-8’)对于解决方案非常重要,正如您在answer中所说的那样,

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

用语言来说:首先通过用一个空格替换所有空格(包括换行符)来清理输入,除了前导空格和尾随空格(删除).然后它在空格处分开,或者在Han字符前面没有“前导”字符(例如打开括号或打开引号)之前,或者在“前导”字符之前.组合线是为了不在水平方向上以超过$maxWidth的像素渲染,除非分割规则不可能(在这种情况下最终渲染可能会溢出).为了在溢出情况下强制分裂的修改并不困难.注意,例如,中文标点符号在Unicode中不被分类为Han,因此除了“前导”标点符号之外,算法之前不能插入换行符.

猜你在找的PHP相关文章