如何自适应实现微信小程序生成海报

前言

说实话,刚收到这个需求时,领导给我演示了一下,以为是个很高大上的功能。找了领导给的小程序生成海报功能的图片做测试,经过我不懈的 努力后 百度后,发现这原来只不过是canvas生成一张图片罢了。,那么问题来了,什么是canvas,呃呃,canvas就是。。。
读者:废话少说,先给看看效果吧,我:好嘞,客官

补充:手机上图片需要网络图片,且先下载准备临时图片地址,最下面有代码演示

(https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.saveImageToPhotosAlbum.html).

效果

原图

点击生成海报

啪,灯神出。。。

好了,效果图也看完了,是不是你想要的效果?如果不是你也不用看下去了。好,接下来咱进入下一个阶段,代码实现

还想多说几句

因为我百度了其他大佬们的代码,发现他们居然没怎么考虑自适应问题。小程序本身就自带了rpx这样的玩意,那我们也就更方便了。先把设计稿放到ps里,Alt+i+i将设计稿缩小为750px的宽,然后直接测量每一个元素的坐标,如下图(相信大家都是一个成熟的前端了,怎么用测量工具就不使用用我来过多说了)

这次真的不多说了,下面上代码

wxml

<!--pages/detail/index.wxml-->
<view class="container"><view class="btn"><button open-type="getUserInfo" bindgetuserinfo="getUserInfo"><view class="text">生成海报</view></button></view><!-- 生成海报 --><view class="poster-box"wx:if='{{isPhotoModel}}' bindtap="setPhotoModel"><canvas canvas-id="mycanvas" style="width:{{posterW}}px;height:{{posterW}}px; "/><image  mode="widthFix" src='{{shareImagePath}}' wx:if='{{shareImagePath}}'></image><view class="close-save">关闭并保存海报</view></view>
</view>

CSS

/* pages/poster/index.wxss */
.container{padding-top: 400rpx;
}
/* 海报弹框 */
.poster-box{position: fixed;top:0;left:0;width: 100%;height: 100%;background: rgba(0,0,0,.4);z-index: 100;
}
.poster-box canvas{position: absolute;top:0;left:10000px;bottom:0;right:0;margin:auto;background: #fff;
}
.poster-box image{width: 90%;position: absolute;top:0;left:0;bottom:0;right:0;margin:auto;
}
.poster-box .close-save{width: 300rpx;position: absolute;left:0;bottom: 10%;right:0;margin:auto;border-radius: 10rpx;line-height: 80rpx;font-size: 30rpx;text-align: center;background: #fff;color: #aaa;}

JS

// pages/detail/index.js
Page({/*** 页面的初始数据*/data: {// 分享海报图片shareImagePath: "",// 分享的小程序码qtsheXcxCode: "/images/image/wx-code.png",// 分享的用户姓名userName: "你的名字",// 分享的用户头像userHeadUrl: "/images/image/head-img.png",// 分享的海报背景图片qtsheBackground: "/images/image/poster-img.png",// 海报弹框isPhotoModel: false,// 海报宽高posterW: 0,posterH: 0,Rpx: 0,},/*** 功能函数 **/// 获取容器高度 提前设置好canvas宽高getContentHeight() {wx.getSystemInfo({success: (res) => {// console.log(res)this.setData({Rpx: res.windowWidth / 750,posterW: res.windowWidth,posterH: res.windowWidth,})}})},// 获取用户信息getUserInfo(res) {console.log(res)// 获取用户信息失败if (res.detail.errMsg !== "getUserInfo:ok") {return false;}this.setData({userName: res.detail.userInfo.nickName,// userHeadUrl: res.detail.userInfo.avatarUrl,// qtsheBackground: "",});this.createNewImg();},// 海报弹框隐藏显示setPhotoModel() {this.setData({isPhotoModel: !this.data.isPhotoModel})},/*** 海报绘制函数 **///将canvas转换为图片保存到本地,然后将图片路径传给image图片的srccreateNewImg() {wx.showLoading({title: '正在生成海报...',mask: true})let that = thislet ctx = wx.createCanvasContext('mycanvas')// 绘制背景this.setBg(ctx);//绘制背景图片this.setBgImage(ctx);// 绘制头像this.setAvatar(ctx);// 名字this.setName(ctx);// 名字下的标题1this.setText({ ctx: ctx, text: "邀请你免费学习", size: 30, x: 150, y: 412, color: "#A2A2A2" });// 名字下的标题2this.setText({ ctx: ctx, text: "混沌学院", size: 30, x: 393, y: 412, color: "#c1bba8" });// 名字下的标题3this.setText({ ctx: ctx, text: "重磅好课", size: 30, x: 536, y: 412, color: "#A2A2A2" });// 绘制线条this.setLine(ctx);// 绘制小程序码this.setQrcode(ctx);// 小程序码旁边的文字this.setText({ ctx: ctx, text: "扫码升级你的思维", size: 30, x: 257, y: 577, color: "#d3d3d3" });this.setText({ ctx: ctx, text: "开课后72小时内免费学习此课程", size: 30, x: 257, y: 634, color: "#d3d3d3" });// 结束绘制ctx.draw()// 保存ctx.save()// 展示海报弹框this.setPhotoModel();//将生成好的图片保存到本地,需要延迟一会,绘制期间耗时setTimeout(() => {wx.canvasToTempFilePath({canvasId: 'mycanvas',success: function (res) {console.log(res)wx.hideLoading()that.setData({shareImagePath: res.tempFilePath});},fail: function (res) {console.log(res.errMsg)wx.showToast({title: '保存失败,请刷新页面重试',icon: 'none'})}}, this)}, 2000)},// 绘制背景setBg(ctx) {let { Rpx } = this.datalet W = 750 * Rpxlet H = 750 * Rpxctx.setFillStyle('#FFFFFF')ctx.fillRect(0, 0, W, H)},// 绘制背景海报setBgImage(ctx) {let { qtsheBackground } = this.datathis.setImage({ ctx: ctx, imageUrl: qtsheBackground, x: 0, y: 0, W: 750, H: 305 })},/** 绘制用户头像* cx cy 是圆心到画布原点坐标* r*2是上面圆的直径,也是头像的宽高*/setAvatar(ctx) {let { Rpx } = this.data// 先画个圆形区域let cx = 83 * Rpx;let cy = 400 * Rpx;let r = 50 * Rpx;ctx.arc(cx, cy, r, 0, 2 * Math.PI);ctx.clip();// 将头像绘制在圆里边let path = this.data.userHeadUrl;this.setImage({ ctx: ctx, imageUrl: path, x: 35, y: 353, W: 100, H: 100 })},// 昵称绘制setName(ctx) {let text = this.data.userName + "我是测试昵称";if (text.length >= 8) {text = text.substring(0, 7) + '...'}this.setText({ ctx: ctx, text: text, size: 34, x: 150, y: 354, color: "#000" });},/*** @title 文字绘制* @params obj object 绘制对象* @params obj.ctx object 画布对象* @params obj.text string 绘制文字* @params obj.size number 绘制文字尺寸* @params obj.x number 绘制文字x坐标* @params obj.y number 绘制文字y坐标* @params obj.color string 绘制文字颜色*/setText(obj) {let { Rpx } = this.datalet ctx = obj.ctx;let text = obj.text || "";let size = obj.size * Rpx || 30;let x = obj.x * Rpx || 0;let y = obj.y * Rpx || 0;let color = obj.color || "black";ctx.setTextBaseline('top')ctx.setFillStyle(color)ctx.setFontSize(size)ctx.fillText(text, x, y)},/*** @title 图片绘制* @params obj object 绘制对象* @params obj.ctx object 画布对象* @params obj.imageUrl string 绘制图片地址(真实地址)* @params obj.x number 绘制图片x坐标* @params obj.y number 绘制图片y坐标* @params obj.W number 绘制图片宽* @params obj.H string 绘制图片高*/setImage(obj) {let { Rpx } = this.datalet ctx = obj.ctx;let imageUrl = obj.imageUrl || "";let x = obj.x * Rpx || 0;let y = obj.y * Rpx || 0;let W = obj.W * Rpx || 0;let H = obj.H * Rpx || 0;ctx.drawImage(imageUrl, x, y, W, H);},// 绘制昵称下的线条setLine(ctx) {let { Rpx } = this.datalet x1 = 50 * Rpx;let y1 = 493 * Rpx;let x2 = 700 * Rpx;let y2 = 493 * Rpx;ctx.setStrokeStyle('#d8d8d8')ctx.moveTo(x1, y1)ctx.lineTo(x2, y2)ctx.closePath()ctx.stroke()},// 绘制小程序码setQrcode(ctx) {let { qtsheXcxCode } = this.datathis.setImage({ ctx: ctx, imageUrl: qtsheXcxCode, x: 50, y: 534, W: 180, H: 180 })},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {// 获取容器高度 需要提前预设好canvas的宽高啊 提前预设好canvas的宽高啊 提前预设好canvas的宽高啊 this.getContentHeight();},
})

下载网络图片保存临时路径

这是一个关键步骤,很重要,我们需要先将网络图片保存到本地,再去绘制海报,图片地址路径需要加入下载白名单
代码如下

/*** 保存网络图片临时地址* @imgSrc string 图片地址* @dataValue string 图片地址存储属性* @func function 回调函数*/ savaImageUrl({ imgSrc, dataValue, func}={}){let that = this;wx.downloadFile({url: imgSrc,success: function (res) {console.log(res);that.setData({ [dataValue]: res.tempFilePath})func();},fail: function (res) {console.log(res.errMsg)wx.showToast({title: '保存失败,请刷新页面重试',icon: 'none'})}})},

当需要下载多张图片时, 调用演示如下

  // 获取用户信息 该函数挂在小程序的button上getUserInfo(res){console.log(res)// 获取用户信息失败if (res.detail.errMsg !== "getUserInfo:ok"){return false;}this.setData({userName: res.detail.userInfo.nickName,userHeadUrl: res.detail.userInfo.avatarUrl,});const { qtsheXcxCode, qtsheBackground ,userHeadUrl } = this.data;wx.showLoading({title: '正在生成海报...',mask: true})const func1 = ()=>{ this.savaImageUrl({imgSrc: userHeadUrl,dataValue: "userHeadUrl1",func:()=>{this.createNewImg()} })}const func2 = ()=>{this.savaImageUrl({imgSrc: qtsheXcxCode,dataValue: "qtsheXcxCode1",func: func1})}const func3 = ()=>{this.savaImageUrl({imgSrc: qtsheBackground,dataValue: "qtsheBackground1",func: func2})}func3();},

保存海报

弄个按钮点击保存当前生成的海报,放在生成canvas图片函数里也行

  // 保存海报saveImg() {let that = this;// 获取用户是否开启用户授权相册wx.getSetting({success(res) {// 如果没有则获取授权if (!res.authSetting['scope.writePhotosAlbum']) {wx.authorize({scope: 'scope.writePhotosAlbum',success() {wx.saveImageToPhotosAlbum({filePath: that.data.shareImagePath,success() {wx.showToast({title: '保存成功'})},fail() {wx.showToast({title: '保存失败',icon: 'none'})}})},fail() {// 如果用户拒绝过或没有授权,则再次打开分享口}})} else {// 有则直接保存wx.saveImageToPhotosAlbum({filePath: that.data.shareImagePath,success() {wx.showToast({title: '保存成功'})},fail() {wx.showToast({title: '保存失败',icon: 'none'})}})}}})},

结语

看完了吧,canvas真的难吗,难!但是我们现在想要实现的效果难吗?现在这个效果就是切图画界面嘛。多去看看文档和大佬们的代码,有些以前的难,也就不难了

需要提前预设好canvas的宽高啊 提前预设好canvas的宽高啊 提前预设好canvas的宽高啊 重要的事情说三遍

使用微信小程序生成海报相关推荐

  1. 微信小程序生成海报 poster

    原生小程序 canvas 小程序-canvas绘图并保存到系统相册 小程序导出朋友圈海报详细记录 逻辑清晰的说明了,原生小程序 canvas 绘制的步骤: 获取 Canvas.context 绘制背景 ...

  2. 微信小程序生成海报可保存海报和分享海报

    最近因为小程序生成海报分享的问题头疼了很久,所以自己总结了一下供大家参考,可以放置用户头像姓名以及商品名称价格和二维码太阳码等,实测可用! 下载链接https://download.csdn.net/ ...

  3. 微信小程序生成海报无法保存到相册

    公司小程序是用uniapp开发的,使用saveImageToPhotosAlbum()保存,在微信开发者工具中和真机调试都能正常运行,代码如下,在安卓真机上可以生成海报但是无法保存,苹果手机上直接无法 ...

  4. 微信小程序生成海报中二维码-----长按识别不了问题及处理方案

    > 问题描述: 小程序某个页面中点击按钮,想要生成带有二维码的图片,后续保存本地.生成图片后转发微信中,后长按图片不会出现识别图中二维码的选项问题. 一年前写过一个分享页,当时大部分可以识别,只 ...

  5. 微信小程序生成海报失败问题解决方法

    很多业务需求需要获取到微信头像,然后用头像和二维码及其他背景图一起生成海报,进行分享.在部分机型会出现生成失败问题.以下是本人排除后发现产生问题的原因和解决方法. 1.安卓机提示downloadFil ...

  6. 微信小程序生成海报带二维码功能

    wxml文件 <view><text class='shareText'>生成海报分享至</text><view class='imgBox'>< ...

  7. 微信小程序生成海报下载到本地手机本地

    里面有注释,这个就不详细说了,把对应的的图片路径换掉,就可以完成运行了 index.js 在这里有一个问题,所以在ctx.draw里面设置了一个定时器,因为官方文档说在ctx.draw回调中会绘制完成 ...

  8. 微信小程序生成海报并保存在本地(组件开发)

    1.将商品图片和二维码生成海报在屏幕中间 子组件代码 <template><view><div class="poster"><div c ...

  9. 微信小程序生成海报wxa-plugin-canvas,避开画布图片不显示和版本的坑

    wxa-plugin-canvas组件文档点击下方卡片链接 wxa-plugin-canvashttps://github.com/jasondu/wxa-plugin-canvashttps://g ...

  10. php 小程序生成海报,微信小程序生成海报

    vivo x9  微信版本7.0.4   系统版本2.6.2 var memberTopicCount = this.data.memberTopicCount;//动态数 var memberFol ...

最新文章

  1. Centos6.4 + PHP5.5.11 + Mysql5.6.16 + Tnginx2.02 + Memcached1.4.17 + Redis2.2
  2. 浏览器下载附件Content-Disposition
  3. JAVA中的枚举小结
  4. background-position 使用方法具体介绍
  5. Linux中使用Linux的vim如何让代码高亮显示
  6. 您的第一个简单的机器学习项目
  7. 中央处理器属于计算机外部设备吗,不属于计算机外部设备的是
  8. LVM逻辑卷管理命令
  9. linux修改resolv自动清除,centos 6.2的/etc/resolv.conf自动清空问题
  10. 网页编写练习 小米闪购
  11. 深入浅出SCSI子系统(六)SCSI 磁盘驱动
  12. L298N驱动模块---51单片机代码
  13. python 听歌识曲_Python实现提取谷歌音乐搜索结果的方法
  14. 51单片机洞洞板用的visio图_万能洞洞板之单片机DIY设计,开启制作之路-可编程逻辑-与非网...
  15. graphpad如何检测方差齐_【求助】急求如何用Graphpad Prism6 做析因设计方差分析?谢谢各位大神...
  16. 歌礼与先声签订利托那韦片供应协议;索迪斯华东物流新仓于上海松江区开业 | 美通企业日报...
  17. ant学习笔记—自定义Ant任务
  18. Linux两台主机之间建立信任关系
  19. vue 实现百度下拉提示搜索功能
  20. CCPC-Wannafly Winter Camp Day1 自闭总结

热门文章

  1. matlab魔方矩阵有哪些,关于matlab 魔方矩阵的1、用前100个自然数创建一个10阶的魔方矩阵,求出每行、每列、所有对角线元素的和,再将矩阵...
  2. 京东商城搜索框特效实现
  3. 紫外分光光度计与紫外可见分光光度计的区别是什么?
  4. 零基础入门微信小程序开发 (2020 版)
  5. 你只管打开这个网站,剩下的交给「卧槽」!
  6. 计算机表格做八折怎么辛,五笔字根表口诀.doc
  7. mysql有rollup函数吗_MySQL-with rollup函数运用
  8. PIR控制器调节器并网逆变器电流谐波抑制策略
  9. opencv 视频处理相关
  10. 神经动力学模型的建立