因有需求要做到用php服务端去生成分享海报,并要求把头像、文字、以及二维码跟海报背景图合并,所以研究了一下php的GD库来实现该需求
本次用到的函数介绍
getimagesize 获取图片的宽高
imagecreatefromjpeg 将图片转换为图片资源型 本次用的是jpeg,更多类型还有jpg、gif等,具体请查百度
imagecreatetruecolor 按照指定宽高画一个图
imagecopyresampled 图片拷贝合并
imagettfbbox 计算文字宽高
imagettftext 将文字放到图片上
imagepng 输出图片
imagedestroy 销毁图片内存
imagecreatetruecolor 创建一块指定宽高的画布
自己封装了个生成海报的方法,直接上代码。
<?php
class Lib_GeneratePoster {
private static $newQrCode; // 缩小后的新二维码图片资源
private static $oriQrCode; // 缩小前原二维码图
private static $newImg; // 合并图片后的图片资源
private static $headerImg; // 头像资源
private static $newHeaderImg; // 放大后的头像资源
private static $headerBlank; // 空白图片跟头像
private static $OriginalPictureWidth = 0; // 原图片宽度
private static $OriginalPictureHeight = 0; // 原图片高度
private static $new_width = 225; // 二维码缩小后的宽度
private static $new_height = 225; // 二维码缩小后的高度
private static $FONT_TTF = __DIR__ . '/ttf/msyh.ttf'; // 字体文件
private static $FONT_SIZE = 23; // 文字大小
/* 生成活动海报图片
* @param $nick_name 用户昵称
* @param $avatar_url 用户头像
*
* */
public static function CreateImg($nick_name, $avatar_url){
$red_package = '图片背景原图';
$img = '二维码图片';
// 计算活动原图宽高
list(self::$OriginalPictureWidth, self::$OriginalPictureHeight) = getimagesize($red_package);
header("Content-type: image/png");
// 缩小二维码图片
self::narrowPicture($img, $avatar_url);
// 创建白板画布
self::createBlank();
// 生成合并后的图片
self::output($red_package, $nick_name, $avatar_url);
}
/* 将二维码图片缩小 && 头像放大
* @param $img 二维码图片
* @param $avatar_url 用户头像
*/
private static function narrowPicture($img, $avatar_url){
$width = 430; // 图片原宽度
$height = 430; // 图片原高度
self::$oriQrCode = imagecreatefromjpeg($img); // 原头像
self::$headerImg = imagecreatefromjpeg($avatar_url); // 新头像
self::$newQrCode = imagecreatetruecolor(self::$new_width, self::$new_height); // 按照新的宽高画一个图
imagecopyresampled(self::$newQrCode, self::$oriQrCode, 0, 0, 0, 0, self::$new_width, self::$new_height, $width, $height);
$header_old_width = 130;
$header_old_height = 130;
$header_new_width = 230;
$header_new_height = 205;
// 新头像宽高
self::$newHeaderImg = imagecreatetruecolor($header_new_width, $header_new_height);
imagecopyresampled( self::$newHeaderImg, self::$headerImg, 0, 0, 0, 0, $header_new_width, $header_new_height, $header_old_width, $header_old_height);
}
/* 海报合并后的图片
* @param $red_package 原背景图
* @param $nick_name 用户昵称
* @param $avatar_url 用户头像
*/
private static function output($red_package, $nick_name, $avatar_url){
// 合并二维码
self::$newImg = imagecreatefrompng($red_package);
imagesavealpha(self::$newImg, true);
// 将二维码海报放到白板画布头像上
imagecopy(self::$headerBlank, self::$newImg ,0, 0, 0, 0, self::$OriginalPictureWidth, self::$OriginalPictureHeight);
// 棕色
$brown = imagecolorallocate(self::$headerBlank, 108,23,6);
// 加字
$text = '图片文字';
// 计算出文字在图片中的宽度
$p = imagettfbbox(self::$FONT_SIZE,0,self::$FONT_TTF,$text);
$txt_width=$p[2]-$p[0];
// 获取文字在图片中居中的x轴
$x = (self::$OriginalPictureWidth - $txt_width) / 2;
imagettftext(self::$headerBlank, self::$FONT_SIZE, 0, $x, 120, $brown, self::$FONT_TTF, $text);
// 输出图片
imagepng(self::$headerBlank);
imagedestroy(self::$headerBlank);
}
/* 创建一块画布把头像放上去
*/
private static function createBlank(){
self::$headerBlank = imagecreatetruecolor(self::$OriginalPictureWidth, self::$OriginalPictureHeight);
$white = imagecolorallocate(self::$headerBlank, 255, 255, 255);
imagefill(self::$headerBlank, 0, 0, $white);
// 将头像放到白色背景上
imagecopymerge(self::$headerBlank, self::$newHeaderImg ,260, 280, 0, 0, 230, 205, 100);
// 放二维码到图片上
imagecopymerge(self::$headerBlank, self::$newQrCode, 257, 557, 0, 0, self::$new_width, self::$new_height, 100);
}
}
本次的TTF文字用的是微软雅黑,下面是下载地址:
链接:https://pan.baidu.com/s/1dHHCq9DiOqLD6ra3Sg0LPw 密码:dl57
大致的逻辑是:
1、生成一块白板画布
2、将二维码、头像合并到白板画布上
3、将背景海报盖到白板画布上合成图片
4、将文字加到合并后的图片上
希望可以帮到有需要的同学