乐趣区

小程序生成海报代码解析

最近趁垃圾分类这个热点,做了一个小程序,实现的功能有

  1. 根据关键词查询垃圾类别
  2. 用户提交垃圾分类信息
  3. 垃圾分类答题活动
  4. 答题分数海报生成

里面有比较重要的模块是答题活动,题目答完之后,会生成分数海报,本次我单独把这个功能拎出来讲下

请扫描体验

这里涉及微信小程序的几个知识点如下

  1. 获取用户个人信息授权
  2. 保存图片到本地授权
  3. canvas
  4. 文件操作

以及下面几个 API

  1. wx.getImageInfo
  2. wx.downloadFile
  3. wx.saveFile
  4. wx.createCanvasContext
  5. wx.canvasToTempFilePath
  6. wx.getSetting
  7. wx.saveImageToPhotosAlbum
  8. wx.authorize
  9. wx.saveImageToPhotosAlbum

获取背景图片

  promiseBdImg: function(){
    const _this = this
    const bdImagePath = '../../static/images/common/'
    return new Promise(function (resolve, reject) {
      wx.getImageInfo({
        src: bdImagePath + "base.png",
        success: function (res) {console.log('promiseBdImg', res)
          resolve(res);
        },
        fail: function(err){console.log('2019062007');
          console.log(err);
        }
      })  
    });
  },

将背景图片提前绘制到 canvas 上,由于绘制海报需要三个图片资源:背景图片、头像、小程序二维码以及文字,能不在一起的尽量提前处理

特别是头像是网络资源,能早点拿到头像信息存储起来最好的

  onReady: function () {
    const _this = this

    // 默认进入页面就生成背景图
    var windowWidth = this.data.windowWidth;
    var posterHeight = this.data.posterHeight;
    this.promiseBdImg().then(res => {console.log('Promise.all', res)
      const ctx = wx.createCanvasContext('shareImg')
      ctx.width = windowWidth
      ctx.height = posterHeight
      console.log(windowWidth, posterHeight)
      // 主要就是计算好各个图文的位置
      ctx.drawImage('../../' + res.path, 0, 0, windowWidth, posterHeight, 0, 0)
      ctx.save() // 对当前区域保存
      ctx.draw()}).then(() => {})    
  },

生成海报图片,这是该模块的核心代码,主要是将图片资源绘制到 canvas 上面,具体坐标定位这个细节还有待完善

generateImage: function(e){
    app.globalData.userInfo = e.detail.userInfo
    let userInfo = e.detail.userInfo
    console.log('userInfo', userInfo)
    // 更新用户信息
    // api.post('更新用户信息的 url', userInfo)
    this.setData({userInfo: e.detail.userInfo});

    console.log('2019062006');
    // 头像
    // let promiseAvatarUrl = new Promise(function (resolve, reject) {//   resolve(wx.getStorageSync('avatarUrl'))
    // }).catch(res=>{//   console.log('catch',res)
    // });

    wx.showLoading({title: '正在生成海报,请稍后'})

    let avatarUrl = userInfo.avatarUrl;
    let nickName = userInfo.nickName;
    let promiseAvatarUrl = new Promise(function (resolve, reject) {
      wx.getImageInfo({
        src: avatarUrl,
        success: function (res) {console.log('promiseAvatarImg', res)
          resolve(res);
        },
        fail: function(err){console.log('2019070501');
          console.log(err);
        }
      })  
    });

    const _this = this

    const qrImagePath = '../../qrcode/'
    let promiseQrcodeImg = new Promise(function (resolve, reject) {
      wx.getImageInfo({
        src: qrImagePath + "gh_d2778c07ec2e_258.jpg",
        success: function (res) {console.log('promiseQrcodeImg', res)
          resolve(res);
        },
        fail: function(err){console.log('2019062007');
          console.log(err);
        }
      })  
    });    

    var windowWidth = this.data.windowWidth;
    var posterHeight = this.data.posterHeight;
    Promise.all([promiseAvatarUrl, promiseQrcodeImg]).then(res => {console.log('Promise.all', res)
      const ctx = wx.createCanvasContext('shareImg')
      ctx.width = windowWidth
      ctx.height = posterHeight
      console.log(windowWidth, posterHeight)
      // 主要就是计算好各个图文的位置
      
      ctx.drawImage(res[0].path,148, 10, 75, 75, 0, 0) // 把图片填充进裁剪的圆形
      ctx.restore() // 恢复
      ctx.save()
      
      ctx.beginPath() // 开始新的区域
      ctx.drawImage('../../' + res[1].path, 128, 266, 94, 94, 0, 0) // 把图片填充进裁剪的圆形
      ctx.restore() // 恢复
      ctx.save()

      ctx.beginPath();
      ctx.setTextAlign('center')
      ctx.setFillStyle('#000')
      ctx.setFontSize(22)      
      ctx.fillText('得分'+_this.data.score, 180, 250)
      ctx.setFontSize(18) 
      ctx.fillText('欢迎'+ nickName +'参加垃圾分类答题活动', 180, 414)
      ctx.stroke()
      ctx.draw(true)

    }).then(() => {wx.hideLoading()
    })
  },

将海报图片保存到本地图片如下所示


  saveImage: function(){
    var windowWidth = this.data.windowWidth;
    var posterHeight = this.data.posterHeight;

    var _this = this
    wx.showLoading({title: '正在保存海报,请稍后'})
    new Promise(function (resolve, reject) {
      wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: windowWidth*2,
        height: posterHeight*2,
        destWidth: windowWidth*2,
        destHeight: posterHeight*2,
        canvasId: 'shareImg',
        success: function (res) {console.log(res.tempFilePath);
          _this.setData({
            prurl: res.tempFilePath,
            hidden: false
          })
          resolve(res)
        },
        fail: function (res) {console.log(res)
        }
      })
    }).then(res => {console.log(res)
      this.save(res)
    })
  },

具体下载图片到本地

save: function(){
      wx.saveImageToPhotosAlbum({
        filePath: data.tempFilePath,
        success(result) {wx.hideLoading()
          wx.showModal({
            showCancel: false,
            title: '提示',
            content: '海报已保存到本地',
            success (res) {if (res.confirm) {console.log('用户点击确定')
              } else if (res.cancel) {console.log('用户点击取消')
              }
            }
          })
          console.log(result)
        }
      })
}

具体代码请移步 https://gitee.com/jgl1210/laj…

,具体如下图所示





有不懂得可以在评论区留言

退出移动版