最近接了一个需求,需要自动生成图片,图片分为三个部分,如下显示
Head 和 Footer 是固定的,Body 部分根据文字生产适应高度的图片,下面上代码, 代码里有详尽注释,代码里有一些特殊逻辑,不过也简单,为大家提供个思路。
// 图片头
$image = ['./img/head.jpg'];
// 初始高度
$height = 0;
// 页面宽度
$width = 1000;
// 创建图片的方法
function createImg($string)
{
mb_internal_encoding("UTF-8"); // 设置编码
// 初始化字符串, 这个字符串是用来做换行的
$content = "";
// 字体
$font = "./img/11.otf";
// 文字的宽度
$width=980;
//字体大小
$size = 35;
// 行数
$line_num = 0;
// 将字符串拆分成一个个单字 保存到数组 letter 中
for ($i = 0; $i < mb_strlen($string); $i++) {
$letter[] = mb_substr($string, $i, 1);
}
foreach ($letter as $l) {
$teststr = $content . " " . $l;
$fontBox = imagettfbbox($size, 0, $font, $teststr);
// 判断拼接后的字符串是否超过预设的宽度
// 注意看后边这两个判断条件, 第一个判断条件是根据字符串长短分隔一条中的换行, 第二个条件是根据特殊字符 ■ 来做每条信息的换行.
if ((($fontBox[2] > $width) && ($content !== "")) || $l == '■') {
$content .= "\n";
$line_num += 1;
}
$content .= $l;
}
// 根据 行数 生成 白色背景图片
$im = imagecreatetruecolor(1000, $line_num * 85);
// 将背景设为白色
$red = imagecolorallocate($im, 255, 255, 255);
imagefill($im, 0, 0, $red);
Imagejpeg($im, './img/bg.jpg', 1000);
// exit();
// 文字图片后边的背景
// todo: 背景图片高度根据文字高度来做, 这样生成的图片宽高就适合
// 现在的背景图是提前做好的, 不适合文字的长短
$backgroundPath = './img/bg.jpg';
$img = imagecreatefromjpeg($backgroundPath); //背景图
// 加上时间, 字体变红
$date = date('Y年m月d日', time()) ;
// 生成星期几
$weekarray=array("日","一","二","三","四","五","六"); //先定义一个数组
$date .= " 星期".$weekarray[date("w")];
$red = imagecolorallocate($img, 255, 0, 0);
imagettftext ( $img, 32, 0, 300, 50, $red, $font, $date );
// 编辑
//设置字体颜色
$black = imagecolorallocate($img, 0, 0, 0);
//字体
imagettftext ( $img, $size, 0, ceil(($width - $fontBox[2]) / 2), 100, $black, $font, $content );
// 生成图片的地址
$filePathDir = './img/';
if (!is_dir($filePathDir)) {
mkdir($filePathDir, 0777, true);
}
// 随机生成一个文件名
$filePath = $filePathDir . time() . rand(0, 999) . '.jpg';
// 生成
imagejpeg($img, $filePath);
return $filePath;
}
// 文章标题数组
$info_title = [
'1.原创|食品过敏原标识管理介绍 (国外篇)',
'2.11111',
'3.22222',
'3.33333',
'4.4444',
'5.5555',
'2.6666',
'6.7777',
'6.8888',
'6.99999',
];
// 组合成一个字符串
$info_title = '■ '.implode('■ ', $info_title);
// 开始生成
$fontpath = createImg($info_title);
// 注意看这块, 图片拼接时 是按顺序来的
// 1 是生成的文字图片
$image[1] = $fontpath;
// 2 是 尾图
$image[2] = './img/foot.jpg';
// 前面需要的图片都弄好了, 开始聚合成一张
// 获取图片基本信息
foreach ($image as $k => $v) {
$source[$k]['source'] = Imagecreatefromjpeg($v);
$res_image[$k] = getimagesize($v);
}
//获取新画布的总高度
foreach ($res_image as $k => $v) {
$new_height = $v[1] * $width / $v[0];###我的新画布固定宽度为1000
$height += $new_height;###计算新画布的高度
$res_image[$k]['height'] = $new_height;
//等比例缩放
$image_p[$k] = imagecreatetruecolor($width, $new_height);
imagecopyresampled($image_p[$k], $source[$k]['source'], 0, 0, 0, 0, 1000, $new_height, $v[0], $v[1]);
}
//创建一个新的画布
$new_image = imagecreatetruecolor($width, $height);
//向画布添加图片
$dst_x = 0;
$dst_y = 0;
foreach ($res_image as $k => $v) {
imagecopy($new_image, $image_p[$k], $dst_x, $dst_y, 0, 0, $v[0], $v[1]);###参数挺多可以参照官方文档呦http://php.net/manual/zh/book.image.php
$dst_y += $v['height'];
}
//添加地址
$date = date('Ymd', time());
$dir = './' . $date;
// 生成唯一文件名
$name = uniqid();
//生成图片
$res_data = Imagejpeg($new_image, './img/' . $name . '.jpg', 1000);