php生成小程序二维码、合成图片
本文是在laravel
框架下实现,且运用的是laravel微信扩展(查看文档EasyWeChat)
首先小程序生成二维码需要access_token
EasyWeChat获取access_token代码
access_token需要appid、secret,我们在根目录下.env文件中配置好appid、secret方便获取
WX_APP_ID = wxxxxxxxxxxxxx5919
WX_APP_SECRET = b2768fexxxxxxxxxxxxxxxxxxxxx45f
在控制器中通过Factory::miniProgram得到实例,就不用在每个页面单独写
EasyWeChat生成二维码代码
用法查看:https://www.easywechat.com/docs/4.1/mini-program/app_code
合成图片
开始写后台生成图片接口,部分变量已注释含义,每一步也注释了
/**
*
* id 测试商品id
* scene 扫码后 传递给小程序的参数
* page 小程序页面地址
* width 二维码宽度
* types 测试商品类型
*
*/
public function get_qrcode_back () {
//获取前端传入的参数
$input = request()->all();
$id = $input['id'];
$scene = $input['scene'];
$page = $input['page'];
$width = $input['width'];
$types = $input['types'];
// 调用生成二维码的函数 如上面微信扩展代码图片
$response = $this->app->app_code->getUnlimit($scene, [
'page' => $page,
'width' => $width,
]);
// 保存小程序码到文件 base_path():项目根目录的绝对路径
if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
$filename = $response->saveAs(base_path().'/storage/app/public/shareImg', 'yc'.$id.'appcode.png');
$path = env('BASE_URL').'/storage/app/public/shareImg/'.$filename;
}else{
$path = "no";
}
// 拿到小程序二维码$path 开始合成分享图
// 这里根据商品类型展示不同的内容
if ($types == 'room') {
// 更具id查询房间数据库数据
$res = DB::table('room')->where('id',$id)->get();
// 背景图
$bg1 = 'https://cdn.irent.top/xcx-canvasgb.jpg';
// 地区(内容而已、可以忽略)
$district = DB::table('const_enum')->find($res[0]->district);
$district_arr = object_to_array($district);
$district_txt = $district_arr['text'];
// 标签(内容而已、可以忽略)
$is_agent = DB::table('const_enum')->find($res[0]->is_agent);
$rent_room_type = DB::table('const_enum')->find($res[0]->room_type);
$rent_type = DB::table('const_enum')->find($res[0]->gender);
$is_agent_arr = object_to_array($is_agent);
$rent_room_type_arr = object_to_array($rent_room_type);
$rent_type_arr = object_to_array($rent_type);
// 文字 (内容而已、可以忽略)
$tip1 = $res[0]->title;
$tip2 = 'HK'.$res[0]->price.'/月';
$tags = $is_agent_arr['text'].'、'.$rent_room_type_arr['text'].'、'.$rent_type_arr['text'];
} else if ($types == 'goods'){
// 更具id查询商品数据库数据
$res = DB::table('goods')->where('id',$id)->get();
// 背景图、文字(内容而已、可以忽略)
$bg1 = 'https://cdn.irent.top/xcx-canvasgb2.jpg';
$tip1 = $res[0]->name;
$tip2 = 'HK'.$res[0]->prices;
}
// 商品、房间图片
$res[0]->images = json_decode($res[0]->images,true);
$resImg = $res[0]->images;
// 开始绘画背景图
$shareBg = imagecreatefromstring(file_get_contents($bg1)); // 最底部背景图
$shareRoom = imagecreatefromstring(file_get_contents($resImg[0])); // 商品图
$shareQr = imagecreatefromstring(file_get_contents($path)); // 二维码图
// 配置颜色
$black = imagecolorallocate($shareBg, 51,51,51);
$gray = imagecolorallocate($shareBg, 102,102,102);
$red = imagecolorallocate($shareBg, 254, 83, 52);
// 配置字体
$font = base_path().'/public/font/SIMHEI.TTF';
// 拼接图片到背景图
imagecopyresampled($shareBg, $shareRoom, 32, 32, 0, 0, 686, 460, imagesx($shareRoom), imagesy($shareRoom));
imagecopyresampled($shareBg, $shareQr, 468.75, 833.75, 0, 0, 200, 200, imagesx($shareQr), imagesy($shareQr));
// 拼接文字
if ($types == 'room') {
imagettftext($shareBg, 24, 0, 80, 560, $black, $font, $tip1);
imagettftext($shareBg, 20, 0, 80, 610, $gray, $font, $tags);
imagettftext($shareBg, 20, 0, 80, 660, $gray, $font, $district_txt);
imagettftext($shareBg, 26, 0, 80, 720, $red, $font, $tip2);
} else {
imagettftext($shareBg, 24, 0, 80, 560, $black, $font, $tip1);
imagettftext($shareBg, 26, 0, 80, 610, $red, $font, $tip2);
}
// 生成图片存入服务器
imagepng($shareBg, base_path().'/storage/app/public/shareImg/yc'.$id.'appshare.png');
$newPath = env('BASE_URL').'/storage/app/public/shareImg/yc'.$id.'appshare.png';
// 图片地址存入数据库
$shareImg['share_img'] = $newPath;
if ($types == 'room') {
DB::table('room')->where('id',$id)->update($shareImg);
} else if ($types == 'goods'){
DB::table('goods')->where('id',$id)->update($shareImg);
}
return json_encode(['code'=>'200','msg'=>'请求成功','newpath'=>$newPath]);
}
注意:
- 字体包:字体包要一起放到服务器上(
注意路径问题,否则会一直包找不到改字体文件
),我这里是放在了项目的public文件夹下面 - EasyWechat:使用方法可以查看文档
- laravel内置路径:
app_path函数返回app目录的绝对路径
base_path函数返回项目根目录的绝对路径
config_path函数返回应用配置目录的绝对路径
database_path函数返回应用数据库目录的绝对路径
public_path函数返回public目录的绝对路径
storage_path函数返回storage目录的绝对路径
配置接口路由
Route::post('/get_qrcode_back', 'TimingApiController@get_qrcode_back');//后台生成小程序分享图
前端调用接口
var data = {
id: _this.data.id, // 房间/商品id
scene: _this.data.id, // 小程序scene值,这里传的也是id值,访问对应房间/商品详情页
page: 'pages/goodsDetail/goodsDetail',
width: 100,
types: 'goods' // room/goods
}
app.api.get_qrcode_back(data, res=>{
console.log(res)
})
// 小程序端我这里封装了api
//function get_qrcode_back(data, callback){
// http('api/get_qrcode_back', 'POST', data, res => {
// typeof callback == 'function' && callback(res.data)
// }, '')
//}
合成图展示
GD 和图像处理 函数
用到的部分GD 和图像处理 函数
- imagecreatefromstring:从字符串中的图像流新建一图像
- imagecopyresampled:重采样拷贝部分图像并调整大小
- imagecolorallocate:为一幅图像分配颜色
- imagettftext:用 TrueType 字体向图像写入文本
- imagepng :以 PNG 格式将图像输出到浏览器或文件