问题需求:
1、文字超出图片大小换行
2、最后一行文字居中显示
thinkphp生成的文字水印只显示一行,需要修改图片处理类
第一步,修改 ThinkPHP\Library\Think\ Image.class.php
修改内容如下:
1、添加 $txt_width 背景图片宽度
/**
* 图像添加文字
* @param string $text 添加的文字
* @param string $font 字体路径
* @param integer $size 字号
* @param string $color 文字颜色
* @param integer $locate 文字写入位置
* @param integer $offset 文字相对当前位置的偏移量
* @param integer $angle 文字倾斜角度
* @param integer $txt_width 背景图片宽度
* @return Object 当前图片处理库对象
*/
public function text($text, $font, $size, $color = '#00000000',
$locate = self::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0,$txt_width = null){
$this->img->text($text, $font, $size, $color, $locate, $offset, $angle,$txt_width);
return $this;
}
第二步,GD库为例 修改 ThinkPHP\Library\Think\Image\Driver\Gd.class.php
1、添加换行标记
if($txt_width){
$txt_max_width = intval(0.8*$txt_width);
$text = "";
for ($i=0;$i<mb_strlen($come);$i++) {
$letter[] = mb_substr($come, $i, 1);
}
foreach ($letter as $l) {
$teststr = $text." ".$l;
$testbox = imagettfbbox($size,$angle,$font,$teststr);
// 判断拼接后的字符串是否超过预设的宽度。超出宽度添加换行
if (($testbox[2] > $txt_max_width) && ($text !== "")) {
$text .= "\n";
}
$text .= $l;
}
}
2、改写文字输出坐标
【这个功能分两种情况!!!!!】
(1)位置最后一行不居中
if($txt_width){
$width = $testbox[2]-$testbox[0];
$x = ($txt_width - $width) / 2; //文字居中
}
imagettftext($this->img, $size, $angle, $x + $ox, $y + $oy, $col, $font, $text);
(2)位置最后一行居中
foreach ($text as $key => $value) {//最后一行居中
$textbox = imagettfbbox($size, $angle, $font,$value);
$txt_height = $textbox[0]-$textbox[7];
$text_width = $textbox[2]-$textbox[0];
if($txt_width){
$x = ($txt_width - $text_width) / 2; //文字居中
}
imagettftext($this->img, $size, $angle, $x + $ox, $y + $oy, $col, $font, $value);
$y = $y+$txt_height+9; // 加9为调整行距
}
整体代码如下:
/**
* 图像添加文字
* @param string $text 添加的文字
* @param string $font 字体路径
* @param integer $size 字号
* @param string $color 文字颜色
* @param integer $locate 文字写入位置
* @param integer $offset 文字相对当前位置的偏移量
* @param integer $angle 文字倾斜角度
*/
public function text($come, $font, $size, $color = '#00000000',
$locate = Image::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0,$txt_width = null){
if($txt_width){
$txt_max_width = intval(0.8*$txt_width);
$text = "";
for ($i=0;$i<mb_strlen($come);$i++) {
$letter[] = mb_substr($come, $i, 1);
}
foreach ($letter as $l) {
$teststr = $text." ".$l;
$testbox = imagettfbbox($size,$angle,$font,$teststr);
// 判断拼接后的字符串是否超过预设的宽度。超出宽度添加换行
if (($testbox[2] > $txt_max_width) && ($text !== "")) {
$text .= "\n";
}
$text .= $l;
}
}
$text = explode("\n",$text?$text:$come);
//资源检测
if(empty($this->img)) E('没有可以被写入文字的图像资源');
if(!is_file($font)) E("不存在的字体文件:{$font}");
//获取文字信息
$info = imagettfbbox($size, $angle, $font, $text);
$minx = min($info[0], $info[2], $info[4], $info[6]);
$maxx = max($info[0], $info[2], $info[4], $info[6]);
$miny = min($info[1], $info[3], $info[5], $info[7]);
$maxy = max($info[1], $info[3], $info[5], $info[7]);
/* 计算文字初始坐标和尺寸 */
$x = $minx;
$y = abs($miny);
$w = $maxx - $minx;
$h = $maxy - $miny;
/* 设定文字位置 */
switch ($locate) {
/* 右下角文字 */
case Image::IMAGE_WATER_SOUTHEAST:
$x += $this->info['width'] - $w;
$y += $this->info['height'] - $h;
break;
/* 左下角文字 */
case Image::IMAGE_WATER_SOUTHWEST:
$y += $this->info['height'] - $h;
break;
/* 左上角文字 */
case Image::IMAGE_WATER_NORTHWEST:
// 起始坐标即为左上角坐标,无需调整
break;
/* 右上角文字 */
case Image::IMAGE_WATER_NORTHEAST:
$x += $this->info['width'] - $w;
break;
/* 居中文字 */
case Image::IMAGE_WATER_CENTER:
$x += ($this->info['width'] - $w)/2;
$y += ($this->info['height'] - $h)/2;
break;
/* 下居中文字 */
case Image::IMAGE_WATER_SOUTH:
$x += ($this->info['width'] - $w)/2;
$y += $this->info['height'] - $h;
break;
/* 右居中文字 */
case Image::IMAGE_WATER_EAST:
$x += $this->info['width'] - $w;
$y += ($this->info['height'] - $h)/2;
break;
/* 上居中文字 */
case Image::IMAGE_WATER_NORTH:
$x += ($this->info['width'] - $w)/2;
break;
/* 左居中文字 */
case Image::IMAGE_WATER_WEST:
$y += ($this->info['height'] - $h)/2;
break;
default:
/* 自定义文字坐标 */
if(is_array($locate)){
list($posx, $posy) = $locate;
$x += $posx;
$y += $posy;
} else {
E('不支持的文字位置类型');
}
}
/* 设置偏移量 */
if(is_array($offset)){
$offset = array_map('intval', $offset);
list($ox, $oy) = $offset;
} else{
$offset = intval($offset);
$ox = $oy = $offset;
}
/* 设置颜色 */
if(is_string($color) && 0 === strpos($color, '#')){
$color = str_split(substr($color, 1), 2);
$color = array_map('hexdec', $color);
if(empty($color[3]) || $color[3] > 127){
$color[3] = 0;
}
} elseif (!is_array($color)) {
E('错误的颜色值');
}
do{
/* 写入文字 */
$col = imagecolorallocatealpha($this->img, $color[0], $color[1], $color[2], $color[3]);
//最后一行不居中
/*if($txt_width){
$width = $testbox[2]-$testbox[0];
$x = ($txt_width - $width) / 2; //文字居中
}
imagettftext($this->img, $size, $angle, $x + $ox, $y + $oy, $col, $font, $text);
*/
foreach ($text as $key => $value) {//最后一行居中
$textbox = imagettfbbox($size, $angle, $font,$value);
$txt_height = $textbox[0]-$textbox[7];
$text_width = $textbox[2]-$textbox[0];
if($txt_width){
$x = ($txt_width - $text_width) / 2; //文字居中
}
imagettftext($this->img, $size, $angle, $x + $ox, $y + $oy, $col, $font, $value);
$y = $y+$txt_height+9; // 加4为调整行距
}
} while(!empty($this->gif) && $this->gifNext());
}
调用实例
private function QrCode($url, $level, $size, $file,$text)
{
vendor('Qrcode.phpqrcode');
$qrcode = new \QRcode();
$qrcode->png($url, $file, $level, $size, 2);
$image = new \Think\Image();
$logo = self::PATH_ELEVATOR.'key/logo.png';
$image->open($file)->thumb(300, 300)->water($logo,5,100)->save($file);
//写入文字
$size = 16;
$background = self::PATH_ELEVATOR.'key/background.png';
$font = self::PATH_ELEVATOR.'key/1.ttf';
$image->open($background)->water($file,array(150,457),100)->text($text,$font,$size,'#ffffff',array(50,826),0,0,600)->save($file);
return file_exists($file) ? $file : false;
}
效果图:
(1)文字不居中
(2)文字居中