项目中需要添加生成海报的功能,需要根据不同的新闻,商品信息生成不同的海报,所以我采用了在背景图上依次打图片水印和文字水印的方式来生成海报,我先上传一张生成的海报,可以看一下是不是你想要的结果
yii添加水印功能
一、给yii框架引入图片水印扩展
项目根目录下执行 composer require --prefer-dist yiisoft/yii2-imagine
要是嫌慢的话可以把composer切换过国内的阿里云镜像,链接,加载成功后会生成vendor/yiisoft/yii2-imagine文件夹
二、扩展的使用
下边是一些使用说明,扩展里还封装了一些其他的方法,一看就能明白,我只是列举出来一些常用的功能
use yii\imagine\Image;
class MarketingController extends BaseController
{
/**
* 裁剪图像。
* @param string $resource 包含文件路径的字符串
* @param int $width 裁剪宽度
* @param int $height 裁剪高度
* @param array $position 开始位置。这必须是一个数组,其中有两个元素表示“x”和“y”坐标。
* @param string $savePath 保存文件路径
*/
public function actionCrop()
{
Image::crop($resource, $width, $height ,$position)
->save(\Yii::getAlias($savePath), ['quality' => 100]);
}
/**
* 在图像周围添加边框。请注意,图像大小将增加“$margin”x 2
* @param string $resource 包含文件路径的字符串
* @param int $margin 要在图像周围添加的帧大小
* @param string $color 边框颜色
* @param int $alpha 帧的alpha值
* @param string $savePath 保存文件路径
*/
public function actionRotate()
{
Image::frame($resource, $margin, $color, $alpha)
->save(\Yii::getAlias($savePath), ['quality' => 100]);
}
/**
* 创建缩略图
* @param string $resource 包含文件路径的字符串
* @param int $width 宽度
* @param int $height 高度
* @param string $mode 如果使用默认的“ImageInterface::THUMBNAIL_OUTBOUND”模式,则会缩放缩略图,以便
它的最小边等于原始图像中对应边的长度。任何超出缩放的缩略图区域将被裁剪,返回的缩
略图将具有准确的宽度和高度指定的。
如果缩略图模式为“ImageInterface::thumbnail_INSET”,则会缩小原始图像,使其完全
包含在缩略图尺寸中。剩下的部分是可以通过
[[Image::$thumbnailBackgroundColor]]和[[Image::$thumbnailBackgroundAlpha]]。
* @param string $savePath 保存文件路径
*/
public function actionThumb()
{
Image::thumbnail($resource, $width, $height, $mode)
->save(\Yii::getAlias($savePath), ['quality' => 100]);
}
/**
* 图片水印。
* @param string $resource 包含文件路径的字符串
* @param string $mark 水印图片路径
* @param array $position 开始位置。这必须是一个数组,其中有两个元素表示“x”和“y”坐标。
* @param string $savePath 保存文件路径
*/
public function actionWatermark()
{
Image::watermark($resource, $mark, $position)
->save(\Yii::getAlias($savePath), ['quality' => 100]);
}
/**
* 文字水印。
* @param string $resource 包含文件路径的字符串
* @param string $content 要写入图像的文本
* @param string $font 文件路径或路径别名
* @param array $position 开始文本的起始位置。这必须是一个数组,其中有两个元素表示“x”和“y”坐标。
* @param string $color 字体颜色,默认为“fff”
* @param string $size 字体大小,默认为12
* @param string $angle 用于编写文本的角度。默认为0
* @param string $savePath 保存文件路径
*/
public function actionText()
{
Image::text($resource, $content, $font,$position,[$color,$size,$angle])
->save(\Yii::getAlias($savePath), ['quality' => 100]);
}
}
小程序码生成
要求生成的海报中有小程序码,用户扫码后可以直接登录到我们的小程序内部,生成小程序码的官方文档地址 。一共提供了三个接口,接口A和B生成的是葵花码,接口C生成的是二维码,我这边用的是接口B,所以就以接口B为例
1、通过申请的appid和secret换取微信access_token(获取的access_token有效期是两个小时,可以做一下缓存,避免重复请求)
2、通过access_token获取小程序码(传入的参数$page和$scene需要注意下,格式容易出错)
3、传递的参数中特殊字符发送到小程序时会被转义,所以需要前端同学在接收时候做一下处理
下面贴代码
class Weixin{
public $appid = '123456789';
public $secret = '123456789';
public function accessToken(){
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$this->appid."&secret=".$this->secret;
$respStr = self::curlGet($url);
$arr = json_decode($respStr, true);
return empty($arr['access_token']) ? '' : $arr['access_token'];
}
/**
* 小葵花二维码
*
* @access public
* @param string $jpg 二维码保存路径
* @param string $page 必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index, 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面
* @param string $scene 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
* @param int $width 二维码的宽度,单位 px,最小 280px,最大 1280px
*/
public function createQR($jpg,$page,$scene,$width){
$cache = \Yii::$app->cache;
$access_token = $cache->get('access_token');
if(!$access_token){
$access_token = $this->accessToken();
$access_token = $cache->set('access_token',$access_token,3600);
}
$url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".$access_token;
$data = [
"page"=>$page,
"scene"=>$scene,
"width"=>$width,
];
$pic = self::curlPost($url,$data);
@ob_end_clean(); //清空缓冲区
$fp = fopen($jpg,'w'); //写入图片
if(fwrite($fp,$pic))
{
fclose($fp);
}
return true;
}
/**
* GET 请求
* @param string $url 路径
*/
public static function curlGet($url){
$header = array(
'Accept: application/json',
);
$curl = curl_init();
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, $url);
//设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 0);
// 超时设置,以秒为单位
curl_setopt($curl, CURLOPT_TIMEOUT, 1);
// 超时设置,以毫秒为单位
// curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500);
// 设置请求头
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
//执行命令
$data = curl_exec($curl);
// 显示错误信息
if (curl_error($curl)) {
print "Error: " . curl_error($curl);
} else {
// 打印返回的内容
curl_close($curl);
return $data;
}
}
/**
* POST 请求
* @param string $url 路径
* @param array $param 参数
*/
public static function curlPost($url,$param){
$curl = curl_init();
if(stripos($url,"https://")!==FALSE){
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
$data = json_encode($param);
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json",
"cache-control: no-cache"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
return("cURL Error #:" . $err);
} else {
return($response) ;
}
}
}
$weixin = new Weixin();
echo $weixin->createQR('123.jpg',$page="pages/enter/enter",$scene="123",$width="280");