PHP使用Grafika合成图片,生成海报图
需求背景:
在小程序上生成海报图,但在保存图片时,只能保存其中的小程序码图片,保存下来的图片过于单调,且无法确认该图片的作用性,所以需要调整为保存一整张海报图。
海报效果图:
需求分析:
在海报图中,背景图、头像、文字、还有小程序码都是各自独立的部分,我们需要把这些图片合并起来,然后输出为一整张图片,这样就可以直接长按保存图片了。
合并图片可以用以下方法:
- 在前端合成,使用画布canvas,把各个元素“画”进去;
- 在后端合成,使用插件Grafika,把各个组成部分合并在一起;
因为当前是在小程序开发这个需求,考虑到未来可能会替换海报上的一些文字、图片等情况,而每次修改小程序代码都需要提交版本审核,耗时耗力,所以决定在后端进行图片合成,输出图片到前端。
注意:若背景图片有透明的部分,处理过后,透明部分会变成黑色,在Grafika中暂未找到能合并透明图片的方法,感觉有点坑,不过有搜到说可以直接用gd来合成,有空再研究研究吧。(目前的解决方法是换张白色背景的图片)
使用Grafika
安装:
composer require kosinix/grafika:dev-master --prefer-dist
生成方法
function create($slogan, $avatar, $qr){// 背景图片$bg_img = 'images/qr_code_bg.png';// 实例化图像编辑器$editor = Grafika::createEditor(['Gd']);// 打开海报背景图$editor->open($backdropImage, $bg_img);$bgWidth = $backdropImage->getWidth();// 生成圆形用户头像$avatarUrlName = 'temp/avatar.png';$this->circular($avatar_url, $avatarUrlName);// 打开用户头像$editor->open($avatarImage, $avatarUrlName);// 重设用户头像宽高$avatarWidth = 310;$editor->resizeExact($avatarImage, $avatarWidth, $avatarWidth);// 用户头像添加到背景图$avatarX = 401;$avatarY = 36;$editor->blend($backdropImage, $avatarImage, 'normal', 1.0, 'top-left', $avatarX, $avatarY);// 打开小程序码$editor->open($qrcodeImage, $qr);// 重设小程序码宽高$qrcodeWidth = 430;$editor->resizeExact($qrcodeImage, $qrcodeWidth, $qrcodeWidth);// 小程序码添加到背景图$qrcodeX = 340;$qrcodeY = 720;$editor->blend($backdropImage, $qrcodeImage, 'normal', 1.0, 'top-left', $qrcodeX, $qrcodeY);// 处理文字$color = new Color('#FFFFFF');$fontPath = Grafika::fontsDir() . '/st-heiti-light.ttc';$fontSize = 50;// 处理用户昵称$nicknameBox = $this->get_text_box($nickname, $fontSize, $fontPath);$fontY = 410;$fontX = ($bgWidth / 2) - ($nicknameBox[0] / 2);$editor->text($backdropImage, $nickname, $fontSize, $fontX, $fontY, $color, $fontPath);$str1 = "邀请您注册成为分销员";$strBox1 = $this->get_text_box($str1, $fontSize, $fontPath);$str1x = ($bgWidth / 2) - ($strBox1[0] / 2);$editor->text($backdropImage, "邀请您注册成为分销员", $fontSize, $str1x, $fontY + 100, $color, $fontPath);$str2 = "一起赚佣金";$strBox2 = $this->get_text_box($str2, $fontSize, $fontPath);$str2x = ($bgWidth / 2) - ($strBox2[0] / 2);$editor->text($backdropImage,'一起赚佣金', $fontSize, $str2x, 1220, $color, $fontPath);// 保存图片$editor->save($backdropImage, $qr);
}
- 使用open()打开图片并获得该图片对象,使用blend()依次合并图片。
- 在处理头像图片时,需要先指定临时的头像文件,便于后续使用。
- 添加文字到图片上时text(),Grafika默认的字体不兼容中文,所以需要指定字体文件路径。
// 生成圆形用户头像
function circular($imgpath, $saveName = ''){$ext = pathinfo($imgpath);$srcImg = null;switch ($ext['extension']) {case 'jpg':case 'jpeg':$srcImg = imagecreatefromjpeg($imgpath);break;case 'png':$srcImg = imagecreatefrompng($imgpath);break;}// 获取图片尺寸$w = imagesx($srcImg);$h = imagesy($srcImg);// 设定图片宽高(正方形)$w = $h = min($w, $h);$newImg = imagecreatetruecolor($w, $h);// 必须imagesavealpha($newImg, true);// 拾取一个完全透明的颜色,最后一个参数127为全透明$bg = imagecolorallocatealpha($newImg, 255, 255, 255, 127);imagefill($newImg, 0, 0, $bg);$r = $w / 2; //圆半径for ($x = 0; $x < $w; $x++) {for ($y = 0; $y < $h; $y++) {$rgbColor = imagecolorat($srcImg, $x, $y);if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {imagesetpixel($newImg, $x, $y, $rgbColor);}}}// 输出图片到文件imagepng($newImg, $saveName);// 释放空间imagedestroy($srcImg);imagedestroy($newImg);
}
- 方法的大概思路是:创建一个正方形的透明图片,通过循环,把透明图片上的圆形部分的像素点画上(替换)头像图片对应的像素点,此时得到的图片就是一个圆形的头像图片。
- 方法中使用了imagecreatetruecolor(),创建真彩图像。此时需要保证使用的图片位数>24(图片文件>属性>详细信息>位深度),否则无法渲染图像成功,结果得到的图片是黑色的。
- 除了使用php内置函数实现圆形图片外,还可以安装Imagick扩展,更方便。
// 获取字符串宽高
function get_text_box($text, $size, $font){$point = imagettfbbox($size, 0, $font, $text);$width = $point[4] - $point[6];$height = $point[1] - $point[7];return [$width, $height];
}
- 使用imagettfbbox()来获取字符串所在的坐标轴,从而可以拿到字符串文本框的宽高,把字符串居中合并到背景图上。
因为目前无法生成用于前端展示的透明背景的图片,所以改成前端展示的还是一个弹窗,弹窗上添加一个长按事件,触发下载合成海报图片到用户相册
// 长按点击事件
downloadQrCode(){wx.showLoading({title: "加载中",mask: true});if(this.data.download_qr_code){this.downloadSaveImage(this.data.download_qr_code);}else{ App._get("user/download_agent_qr_code", {}, (result) => {if(!result.res){wx.showToast({ icon: 'none', title: result.msg });return false;}this.setData({download_qr_code: result.data.url});this.downloadSaveImage(result.data.url);}, null, (res) => {wx.hideLoading();});}
},
/*** 下载图片,并保存到用户相册* @param {string} url 图片地址*/
downloadSaveImage(url){wx.getImageInfo({src: url,success: function (ret) {var path = ret.path;wx.saveImageToPhotosAlbum({filePath: path,success(result) {wx.hideLoading();wx.showToast({ icon: 'none', title: "已保存图片到相册" });},fail(result) {wx.hideLoading();if(result.errMsg.indexOf("saveImageToPhotosAlbum:fail auth deny") !== -1){wx.showToast({ icon: 'none', title: "请允许小程序“保存图片到相册”" });}console.log(result)}});},fail: function(result){wx.hideLoading();console.log(result)}});
},
- App._get() 为发送get请求公共方法
参考:
Grafika官方文档
PHP 将图片切成圆角
PHP使用Grafika合成图片,生成海报图相关推荐
- 前端生成海报图:html2canvas 生成海报图/网页html转图片
html2canvas 生成海报图 <html><head> <title>生成海报图Demo</title> </head><bod ...
- html2canvas手机黑屏,html2canvas 生成海报图 开发中遇到的问题
ios里,生成的图片不显示 canvas.toDataURL('image/jpeg', 1.0) 使用image/jpeg格式,在指定图片格式为 image/jpeg 或 image/webp的情况 ...
- uniapp app端使用html2canvas和renderjs实现生成海报图
uniapp app端使用html2canvas和renderjs实现生成海报图 原本app端是无法使用html2canvas的因为,app端不支持浏览器js. 不过我在uniapp里面看到了rend ...
- tp5.0 FAST 生成海报图
推销部门的海报,大致类容都差不多,经常会修改一些简介,诊疗范围,擅长病种等等,刚开始想到的是利用扩展截图然后去下载,网上的例子倒是不多,目前有两个例子 zyan/url2pic-sdk CSDN地址 ...
- android 照片拼接长图_Android拼接合并图片生成长图-阿里云开发者社区
Android拼接合并图片生成长图 代码实现合并两张图片,以第一张图片的宽度为标准,如果被合并的第二张图片宽度和第一张不同,那么就以第一张图片的宽度为准线,对第二张图片进行缩放. 假设根目录的Pict ...
- 微信小程序canvas合成图片(海报),生成的图片展示不出来,或者空白。
背景: 1.用户点击分享朋友圈,将二维码与一张背景图合成一张图片,然后将其显示. 2.用户点击保存图片将图片保存到手机相册里面. 问题: 用户点击分享盆友圈合成后的图片显示空白.控制台可以打印出来链接 ...
- vue- canvas生成海报图
此图为生成的海报图. git链接:https://github.com/sunniejs/vue_canvas_poster 1.通过cnpm安装 cnpm i vue-canvas-poster - ...
- 在微信小程序中实现生成海报图并保存到相册
效果图镇楼: 技术依赖: 弹窗 (vant-weapp 提供的 van-popup 组件) 海报图 (wx-canvas-2d 工具) 弹窗组件的使用方式可以点击上面链接查看,本篇主要讲解海报图绘制方 ...
- vue-canvas生成海报图
此图为生成的海报图. git链接:https://github.com/sunniejs/vue_canvas_poster 文档:https://sunniejs.github.io/vue-can ...
最新文章
- 摄像头ISP系统原理(上)
- HDU2544(Dijstra算法)
- [转载]MVC、MVP以及Model2(上)
- 有助于建立使用者对套件的信任 GitHub释出管理服务
- MFC中显示一张位图
- 大家推荐一下开源的博客和论坛整合在一起的.net系统
- 南昌大学c语言程序设计,南昌大学C语言程序设计试卷C语言2.doc
- 六问阿里云计算安全,全面解析阿里云ECS服务器的计算安全进化之路
- 一般的病毒通过注册表自启动的方式不断完善中。。。。
- Unity3D设置天空盒skybox
- PR短视频转场预设 60个摇晃抖动效果过渡合集
- Power BI的基本操作
- function func() { for(var i=0; i<3; i++) { setTimeout(()=>{ consol
- iphone应用隐私政策_如何在iPhone上“隐藏”联系人以获得更大的隐私
- java 虚函数_Java的虚方法
- 一键体验安全快捷外贸收款服务,PingPong福贸满足你的个性化需求
- 计算机重启后桌面文件全部丢失,蓝屏后桌面文件丢失,电脑蓝屏桌面文件丢失...
- 2022年湖北省大学生电子设计竞赛A题(单项交流电子负载)赛后总结
- 如何批量提取文件名到excel表
- u盘数据丢失可以恢复吗?教你3种轻松把u盘数据恢复的方法