微信小程序 —— canvas生成海报图与分享
整体思路
- 获取手机屏幕大小去依据设计尺寸比例调整 —
wx.getSystemInfo
- 网络图片、base64图片保存到到本地临时文件路径
- canvas绘制图片 —
wx.createCanvasContext
- 获取用户相册权限 —
wx.getSetting
- canvas海报保存到本地临时文件路径 —
canvasToTempFilePath
- canvas图片保存到本地相册 —
saveImageToPhotosAlbum
效果图
代码示例
wxml
<block wx:if="{{canvasType}}"><canvas class="canvas" canvas-id="shareCanvas" bindtouchstart="start" bindtouchmove="move" bindtouchend="end"></canvas>
</block><view bindtap="shareBtn">保存分享图片</view>
js
// 点击保存图片按钮shareBtn() {setTimeout(() => {this.getSysInfo()}, 200)},
//获取图片信息和屏幕尺寸getSysInfo() {let that = thislet bgImgUrl = this._mapHttpToHttps(that.data.canvasInfoData.posterUrl)let iconUrl = this._mapHttpToHttps(that.data.canvasInfoData.avatar)wx.getSystemInfo({success(res) {that.setData({canvasWidth: res.windowWidth,canvasHeight: res.windowHeight})that.getImginfo([bgImgUrl, iconUrl], 0);}})},
// 获取图片信息getImginfo(urlArr, _type) {let that = this;wx.getImageInfo({src: urlArr[_type], //服务器返回的带参数的小程序码地址success: function (res) {//res.path是网络图片的本地地址if (_type === 0) { //背景图片that.setData({bgImgUrl: res.path,})that.getImginfo(urlArr, 1)} else { //头像图片that.setData({iconUrl: res.path,loadType: true,iconWidth: res.width,iconHeight: res.height,})// 创建canvas图片that.canvasImg();}},fail: function (res) {//失败回调console.log('错误-res', _type, res)}});},
// 将http转为https_mapHttpToHttps(rawUrl) {if (rawUrl.indexOf(":") < 0) {return rawUrl}const urlCompnent = rawUrl.split(":")if (urlCompnent.length === 2) {if (urlCompnent[0] === 'http') {urlCompnent[0] = 'https'return `${urlCompnent[0]}:${urlCompnent[1]}`}}return rawUrl},
生成图片 绘制canvas
canvasImg() {let that = this;wx.showLoading({title: '图片正在生成'});var x = this.data.canvasWidth / 750; //设置相对canvas自适应根元素大小const ctx = wx.createCanvasContext('shareCanvas', this);ctx.drawImage(this.data.bgImgUrl, 0, 0, 750 * x, 1334 * x);//方形二维码框ctx.save();ctx.fillStyle = "#fff";ctx.fillRect(560 * x, 1144 * x, 160 * x, 160 * x);ctx.drawImage(this.data.base64Url, 570 * x, 1155 * x, 140 * x, 140 * x);ctx.restore();//圆形头像框//圆形头像框ctx.save();ctx.beginPath();ctx.arc(150 * x, 800 * x, 90 * x, 0, 2 * Math.PI);ctx.clip();ctx.fillStyle = "#fff";//头像 // ctx.drawImage(this.data.iconUrl, 60 * x, 710 * x, 180 * x, 180 * x);//图片长宽let h = this.data.iconHeightlet w = this.data.iconWidth//宽高比let dw = 180 / this.data.iconWidthlet dh = 180 / this.data.iconHeight// 裁剪图片中间部分if (w > 180 && h > 180 || w < 180 && h < 180) {if (dw > dh) {ctx.drawImage(this.data.iconUrl, 0, (h - 180 / dw) / 2, w, 180 / dw, 60 * x, 710 * x, 180 * x, 180 * x)} else {ctx.drawImage(this.data.iconUrl, (w - 180 / dh) / 2, 0, 180 / dh, h, 60 * x, 710 * x, 180 * x, 180 * x)}}// 拉伸图片else {if (w < 180) {ctx.drawImage(this.data.iconUrl, 0, (h - 180 / dw) / 2, w, 180 / dw, 60 * x, 710 * x, 180 * x, 180 * x)} else {ctx.drawImage(this.data.iconUrl, (w - 180 / dh) / 2, 0, 180 / dh, h, 60 * x, 710 * x, 180 * x, 180 * x)}}ctx.restore();ctx.beginPath()ctx.moveTo(0, 1010 * x);ctx.lineTo(750 * x, 1010 * x);ctx.strokeStyle = "#F0F5F8";ctx.stroke();ctx.closePath();//名字ctx.save();ctx.fillStyle = '#3C3C3C';ctx.font = 'normal bold 17px sans-serif';ctx.fillText(`${this.data.canvasInfoData.name}`, 272 * x, 790 * x);ctx.restore();//等等XXXXXXXXXXXXXXXXXXXctx.save()let textLength = ctx.measureText(this.data.currentTask).width// 长度按照文字长度计算 218 * xlet rectX = (708 * x) - textLength - 5 //476 * xthat.draw(ctx, rectX, 848 * x, textLength + 10, 43 * x, 5, '#fff', '#008CD6')ctx.restore();// 参与人数ctx.save()that.draw(ctx, 20 * x, 40 * x, 240 * x, 55 * x, 15, 'rgba(0, 0, 0, 0.3)', 'rgba(0, 0, 0, 0)');ctx.fillStyle = '#fff'; // 文字颜色ctx.setTextAlign('center');ctx.font = 'normal 400 13px sans-serif';ctx.fillText(`超过${this.data.canvasInfoData.participantsCount}人参与`, 140 * x, 76 * x);ctx.restore();ctx.draw();that.setData({canvasType: true});setTimeout(() => {this.savePoster()}, 300)wx.hideLoading();},
保存海报到相册
// 授权 getSetting检测用户有没有开启相册权限 有的话直接保存 没有的话弹到权限页面让用户授权savePoster() {let that = this;wx.showLoading({title: '正在保存',mask: true,});wx.getSetting({success(res) {if (res.authSetting['scope.writePhotosAlbum']) {that.saveImg()} else if (res.authSetting['scope.writePhotosAlbum'] === undefined) {wx.authorize({scope: 'scope.writePhotosAlbum',success() {that.saveImg()},fail() {wx.hideLoading();that.authConfirm()}})} else {wx.hideLoading();that.authConfirm()}}})},
// 授权拒绝后,再次授权提示弹窗authConfirm() {let that = thiswx.showModal({content: '检测到您没打开保存图片权限,是否去设置打开?',confirmText: "确认",cancelText: "取消",success: function (res) {if (res.confirm) {wx.openSetting({success(res) {if (res.authSetting['scope.writePhotosAlbum']) {that.saveImg();} else {wx.showToast({title: '您没有授权,无法保存到相册',icon: 'none'})}}})} else {wx.showToast({title: '您没有授权,无法保存到相册',icon: 'none'})}}});},
// 图片保存到本地saveImg() {wx.canvasToTempFilePath({canvasId: 'shareCanvas',quality: 1,success: function (res) {wx.hideLoading();var tempFilePath = res.tempFilePath;wx.saveImageToPhotosAlbum({filePath: tempFilePath,success(res) {wx.showModal({content: '海报保存成功,你可以从手机相册中把海报分享到朋友圈',showCancel: false,confirmText: '好的',confirmColor: '#333',})},fail: function (res) {wx.showToast({title: '保存失败',icon: 'none',duration: 2000});}})}}, this);}
问题总结
- 生成的头像显示不全
找到一篇文章解决了这个问题 感谢 canvas实现图片拉伸、压缩与裁剪 - 文字的描绘位置 textBaseline 的介绍
- 绘制圆角矩形 传送带
- canvas的
drawImage
方法只支持本地图片,不支持网络图片 base64保存本地地址 - 绘制顺序影响显示,合理使用
save()
和restore()
- 在page页面中,this是默认的,但是在自定义组件中则需要指定this
- 保存图片的时候必须打开调试才能保存,不打开就保存不了是因为需要配置
https
的域名
后端返回的如果是域名下的http
图片就需要去处理变成https
微信小程序 —— canvas生成海报图与分享相关推荐
- mpvue 微信小程序canvas生成海报
mpvue 微信小程序canvas生成海报 效果 贴代码 html <template><!--index.wxml--><view class="poster ...
- 微信小程序合成海报_微信小程序 canvas生成海报图片模糊问题
一.制作正常显示海报,生成二倍海报隐藏 代码如下 {{sendName}} 保存图片 /*css*/ .btn { width: 300rpx; height: 90rpx; line-height: ...
- 小程序canvas生成海报 字体在背景图下方
小程序canvas生成海报 字体在背景图下方 图片是异步加载 可以放在回调里设置字体 也可以延迟放置 如果还有更好的方法可以留言
- 小程序canvas生成海报
小程序canvas生成海报,画布转图片后可直接保存图片到系统相册: 海报素材使用图片宽750px: 注: 画布转图片时参数destWidth 值 须 * dpr 否则IOS测试生成的图片是模糊的: . ...
- 微信小程序canvas画价格走势图(一)
今天是周二,今天来开一个新坑吧.最近花了整整两个工作日的时间画了一个微信小程序端的价格走势图,现在来分享一下经验. 因为内容比较多,所以打算这次分为多篇博客来写,这样一篇博客的内容就会更少.更清晰.下 ...
- uniapp微信小程序canvas生成简单海报并下载
今天项目接到个任务,就是手写canvas海报,并能下载图片.百度了很多海报组件,都不尽人意.萌生了自己手写海报的想法. 话不多说先贴文档 uni-app官网 其实该文档和微信小程序类似 最终效果,微信 ...
- 微信小程序实现生成海报并且保存本地
首先使用微信小程序提供的canvasapi将第二张图显示的海报画出来 然后调用保存本地的接口 wx.saveImageToPhotosAlbum({})将图片保存在本地相册中 首先我们需要在页面上创建 ...
- 小程序canvas生成海报保存至手机相册
小程序canvas画图保存至手机相册 (1)可直接展示生成的海报 .因手机分辨率不同可能导致生成的海报会有细微差别,这里隐藏canvas海报,页面正常设置海报样式保存时保存隐藏的canvas海报 (2 ...
- 微信小程序 canvas 合成海报
1.先百度了解canvas相关文档: 2.了解微信小程序授权登录与授权登录下保存图片权限问题: 3.canvas标签属性不能是display:none: <canvas class=" ...
最新文章
- 在 CUDA C/C++ kernel中使用内存
- 所有顶点对最短路径问题(图的应用)
- PAT甲级1061 Dating:[C++题解]字符串处理(C语言格式控制牛逼!)
- debian下ror新建项目报错解决
- ThreadLocal实现线程范围内的共享变量
- 60页论文综述深度学习优化方法,出自UIUC
- 看CarbonData如何用四招助力Apache Spark
- Netty粘包拆包问题说明、演示拆包粘包情况代码以及解决
- Python 中遇到note: see declaration of '_ts'
- 华为鸿蒙系统适合机型,华为鸿蒙os2.0系统适用哪些机型
- c语言仓库即存储器,计算机基础4
- __main__.py:AttributeError: module 'labelme.utils' has no attribute 'draw_label'
- Discuz! 7.2 二次开发基础 (一)
- ARC有效的工程中导人非ARC的代码/liberary的设置方法
- cad 打开硬件加速卡_如何提高CAD运行速度
- c++运行错误: string subscript out of range
- 2.CPU体系架构-寄存器
- 2022年认证杯SPSSPRO杯数学建模C题(第一阶段)污水流行病学原理在新冠疫情防控方面的作用求解全过程文档及程序
- 深入理解PHP中的ob_flush和flush的区别
- Elliptic Curve Cryptography: finite fields and discrete logarithms
热门文章
- 抑郁焦虑测试软件可信度,做题自测抑郁症可靠吗
- 怎么删除微信的手机充值服务器,微信如何一键清空账单?全部删除的方法
- imuupdate() 解算
- 一起来学习网站SEO优化工作流程到底怎么做?
- 百度云盘照片导入华为相册里_百度网盘传送列表怎样导入手机相册_手机百度网盘下载到相册...
- win10 任务栏通知区图标不见了
- Switch新机发布引全球吐槽,老任给牙膏厂上了一课,这波是等等党输了
- yii mysql gii_yii中gii如何使用
- (译)快速指南:用UIViewPropertyAnimator做动画
- 通过SqlDbx导出*.sql,然后倒入到SQLServer2005