PHP 根据文字内容添加图片上实现自动换行的小程序

前进的动力来自很多东西,渴望也好,向往也好,压力也好。 总之是源于人对更好的事物的追求。


想要变成大牛,就永远不要失去这种渴望,这种追求。


最近这一周一直在鼓捣一个将用户输入的文字加载到图片上面的功能,因为用户会输入大量的文体,所以势必需要实现换行这个功能。

简单来说这个功能的实现涉及到两个部分,第一部分就是文字如何添加到图片上,第二个部分是文字如何实现自动换行。

第一个功能涉及到imagettftext这个函数,第二个功能涉及到数组,以及imagettfbbox这个函数。


第一个功能没有太多可以分析的地方,前面也写很不少关于这个函数的分析。第二个功能,也在上一篇提到过,需要注意的在imagettftext中实现换行是对文本添加\n这个换行符号。


function creatPic($identity,$story,$background,$username = ''){
	if($username == '') $username = '用户';
	$modelImgPath = 'proud/model.jpg';//模板路径
	$logoImgPath = 'proud/'.$background.'.jpg';//背景图路径
	
	$img = imagecreatefromjpeg($modelImgPath);
	$logo = imagecreatefromjpeg($logoImgPath);
	$logSize = getimagesize($logoImgPath);
	
	$width = imagesx($img);//得到背景图像的宽
	$height = imagesy($img);//得到背景图像的高
	
	$modelSize = getimagesize($modelImgPath);
	/*getimagesize()获得图像大小*/
	
	imagecopy($img,$logo,intval(($modelSize[0]-$logSize[0])/2),intval(($modelSize[1]-$logSize[1])/2),0,0,$logSize[0],$logSize[1]);
	
	putenv('GDFONTPATH=' . realpath('.')); //如果载入字体文件时出错,可以试着加这句
	
	$fontSize = 60;//像素字体
	$fontColor = imagecolorallocate($img,133,37,0);
	$font = 'fonts/MSYH.TTF';// story 的字体
	$font1 = 'fonts/SIMSUN.TTC'; //引号以及医脉通用户的字体
	$font2 = 'fonts/SIMYOU.TTF';
	
	$title_len = mb_strwidth($story,'utf-8')/2;//$title_len 判断story的字符串长度,中文两字符,英文1字符
	
	
	//$a = story的字体大小,磅值;$b = 引号的磅值
	if ($title_len <=7){
		$a = 40;	$b = 80;
	}elseif ($title_len <= 17){
		$a = 38;	$b = 75;
	}elseif($title_len<=24){
		$a=32; $b = 70;
	}elseif($title_len<=33){
		$a=26; $b = 65;
	}elseif ($title_len<=39){
		$a = 25;	$b = 60;
	}elseif ($title_len<=56){
		$a = 23;	$b = 58;
	}elseif ($title_len<=80){
		$a = 20;	$b = 55;
	}elseif ($title_len<=98){
		$a = 18;	$b = 53;
	}else {
		$a = 17;	$b = 53;
	}
	$fontSize = $a;//设置story的字体磅值
	
	//对story实现自动换行
	$text_1 = autowrap($fontSize,0,$font,$story,440);
	
	$number_line = $text_1[1];
	$text_1 = $text_1[0];
	

	$fontBox = imagettfbbox($fontSize,0,$font,$text_1);//imagegettfbox这个函数是为了获得文本的最终占位的像素值
	
	$x =ceil(($width-($fontBox[2]-$fontBox[0]))/2)-1.5;//设置居中显示的位置
	
	
	$fontSize_yinhao = $b;//引号的具体大小
	$text_2 ='“';//左边的引号
	$text_3 ='”';//右边的引号
	//下面这段函数 判断引号的位置,如果只有一行,那么引号在两边,如果多行,右边的引号下移
	if ($a == 40){
		$x2 = $width/2 -220-50*0.5*96/72-$b*96/72*0.45;
		$y2 = 300 ;
		$x3 = $width/2 + 220 + 50*0.5*96/72- $b*96/72*0.45;
		$y3 = 310;
	}else{
		$x2 = $width/2 -220-50*0.5*96/72-$b*96/72*0.45;
		$y2 = 230 + $b*96/72*0.45;
		$x3 = $width/2 + 227 + 50*0.5*96/72- $b*96/72*0.45;
		$y3 = 240 + $b*96/72*0.45 + ($fontBox[1] - $fontBox[6]);
	}
	
	$username = "@".$username;//用户名
	$title_content = $identity;//用户身份
	$title1= "来自";
	$title2 = "的感恩";
	
	$title_content_sum =  $title1.$title_content.$title2;//将所有文本组合成一行
	
	$title_content_len = mb_strwidth($title_content,'utf-8');//计算用户输入的标题 下面计算如果大于4个字符就换行
	
	$title_fontsize = 35;//设置用户输入字体的磅值
	
	
	$title_fontBox = imagettfbbox($title_fontsize, 0, $font,$title_content_sum );
	$title1_fontBox = imagettfbbox($title_fontsize-5, 0, $font,$title1 );
	$title2_fontBox = imagettfbbox($title_fontsize-5, 0, $font,$title2 );
	$title_content_fontBox = imagettfbbox($title_fontsize, 0, $font,$title_content );
	$username_fontBox = imagettfbbox(16, 0, $font,$username );
	if ($title_content_len >= 12){
		imagettftext($img,$title_fontsize-5,0,ceil(($width-$title1_fontBox[2])/2),830,$fontColor,$font,$title1);
		imagettftext($img,$title_fontsize-5,0,ceil(($width-$title2_fontBox[2])/2),970,$fontColor,$font,$title2);
		imagettftext($img,$title_fontsize,0,ceil(($width-$title_content_fontBox[2])/2),905,$fontColor,$font,$title_content);
	}else {
		imagettftext($img,$title_fontsize,0,ceil(($width-$title_fontBox[2])/2),905,$fontColor,$font,$title_content_sum);
		//imagettftext($img,$title_fontsize,0,ceil(($width-$title_fontBox[2])/2)+1,905,$fontColor,$font,$title_content_sum);
		//imagettftext($img,$title_fontsize,0,ceil(($width-$title_fontBox[2])/2)-1,905,$fontColor,$font,$title_content_sum);
	}
	
	imagettftext($img,$fontSize,0,$x,180+($a-45)*96/72,$fontColor,$font,$text_1);//字体验证码
	imagettftext($img,$fontSize_yinhao,0,$x2+5,$y2-100,$fontColor,$font1,$text_2);
	imagettftext($img,$fontSize_yinhao,0,$x3-15,$y3-100,$fontColor,$font1,$text_3);
	$fontColor = imagecolorallocate($img,164,164,164);
	imagettftext($img,16,0,ceil(($width-$username_fontBox[2])/2),1000,$fontColor,$font2,$username);
	
	
	header("centent-type:image/jpeg");
	$newPicName = time().rand(1,10000);
	$newImgPath = 'uploadfile/pictures/'.$newPicName.'.jpg';
	imagejpeg($img,$newImgPath,75); 
	return $newPicName;
}


这是项目中写的代码,属于简单的人为测试的结果。在写了这个版本之后我一直想写一个自动识别,不用人为的设置$a,$b参数的方式。

经过不少分析,我发现imagettfbbox这个函数可以判断分行之后文本域的大小(之前的理解出现了错误),那么我就可以通过这个函数判断写出的文本的宽和高。

<?php
// header('Content-type: image/png');
mb_internal_encoding("UTF-8");
$img = imagecreatetruecolor(400, 200);
$width = 400;
$height = 200;
// $radio = $width/$height;
$white = imagecolorallocate($img, 255, 255, 255);
$fontfile = './MSYHBD.TTF';



$text = '没有时间。没有时间。没有时间。没有时间。没有时间。没有时间。';
$text_len =  mb_strwidth($text)/2;// 这是中文字符的个数
echo "text_len=".$text_len."<br />";
//$text_str =mb_strlen($text);
//echo "text_str=".$text_str."<br />";

$x = sqrt($text_len);//获得一个初始的字数安排
echo "x=".$x."<br />";

$px = ceil($width / (2*$x));// 获得一个初始的像素
echo "px=".$px."<br />";

$fontsize = ceil($px*72/96);//获得一个初始的字体磅值
echo "fontsize=".$fontsize."<br />";


function autowrap($fontsize, $angle, $fontface, $string, $width) {
// 这几个变量分别是 字体大小, 角度, 字体名称, 字符串, 预设宽度
 $content = "";

 // 将字符串拆分成一个个单字 保存到数组 letter 中
 for ($i=0;$i<mb_strlen($string);$i++) {
  $letter[] = mb_substr($string, $i, 1);
 }
 foreach ($letter as $l) {
  $teststr = $content." ".$l;
  $testbox = imagettfbbox($fontsize, $angle, $fontface, $teststr);//这个里面是磅值
  // 判断拼接后的字符串是否超过预设的宽度
  if ((($testbox[2]-$testbox[0]) > $width) && ($content !== "")) {
   $content .= "\n";

  }
  $content .= $l;
 }
 return $content;
}


$a = autowrap($fontsize,0,$fontfile,$text,$width);
$text_change = $a;
// $line_numbers = $a[1];

$text_fontBox = imagettfbbox($fontsize, 0, $fontfile, $text_change);
$text_height = $text_fontBox[1]-$text_fontBox[7];
$text_width = $text_fontBox[2]-$text_fontBox[0];



while ($text_height > $height  || $text_height < ($height -round($fontsize*96/72)*1.8)) {
	if ($text_height > $height ) {		
		$fontsize = $fontsize-1;
	}elseif ($text_height < ($height -round($fontsize*96/72)*1.8)) {
		$fontsize = $fontsize+1;
	}
	$a =  autowrap($fontsize,0,$fontfile,$text,$width);
	$text_fontBox = imagettfbbox($fontsize, 0, $fontfile, $text_change);
	$text_height =$text_fontBox[1]-$text_fontBox[7];
	$text_width = $text_fontBox[2]-$text_fontBox[0];
}
$text_width = $text_fontBox[2]-$text_fontBox[0];
if ($text_width >$width || $width-$text_width >$fontsize*96/72*1.2) {
	$fontsize = $fontsize - 2;
}
echo"最终的字体大小:".$fontsize."<br />";
imagettftext($img, $fontsize, 0,0, (imagettfbbox($fontsize,0,$fontfile,"的")[1]-imagettfbbox($fontsize,0,$fontfile,"的")[7]), $white, $fontfile, $text_change);

$name = time().rand(0,1000);

imagejpeg($img,'./'.$name.'.jpg');
imagedestroy($img);


?>


具体代码就是这样。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值