微信小程序前端生成图片并保存本地

198 阅读3分钟

1:使用canvas绘图

①首先创建canvas画布,我把画布定位设成负的,是为了不让它显示在页面上,是因为我尝试把canvas通过判断条件动态的显示和隐藏,在绘制的时候会出现问题,所以采用了这种方法,这里还有一定要设置画布的大小。

<canvas canvas-id="myCanvas" style="width: 690px;height:1085px;position: fixed;top: -10000px;"></canvas>

②创建好画布之后,先绘制背景图,因为背景图我是放在本地,所以获取 canvas 组件 canvas-id 属性,通过createCanvasContext创建canvas的绘图上下文 CanvasContext 对象。 使用drawImage绘制图像到画布,第一个参数是图片的本地地址,后面两个参数是图像相对画布左上角位置的x轴和y轴,最后两个参数是设置图像的宽高。

const ctx = wx.createCanvasContext('myCanvas')

ctx.drawImage('/img/study/shareimg.png', 0, 0, 690, 1085)

③创建好背景图后,在背景图上绘制头像,文字和数字。通过getImageInfo获取头像的信息,这里需要注意下在获取的网络图片要先配置download域名才能生效,具体在小程序后台设置里配置。 获取头像地址,首先量取头像在画布中的大小,和x轴Y轴的坐标,这里的result[0]是我用promise封装返回的一个图片地址

let headImg = new Promise(function (resolve) {
        wx.getImageInfo({
          src: `${app.globalData.baseUrl2}${that.data.currentChildren.headImg}`,
          success: function (res) {
            resolve(res.path)
          },
          fail: function (err) {
            console.log(err)
            wx.showToast({
              title: '网络错误请重试',
              icon: 'loading'
            })
          }
        })
      })
      
let avatarurl_width = 60, //绘制的头像宽度
    avatarurl_heigth = 60, //绘制的头像高度
    avatarurl_x = 28, //绘制的头像在画布上的位置
    avatarurl_y = 36; //绘制的头像在画布上的位置
    
    ctx.save(); // 先保存状态 已便于画完圆再用
    ctx.beginPath(); //开始绘制
    //先画个圆   前两个参数确定了圆心 (x,y) 坐标  第三个参数是圆的半径  四参数是绘图方向  默认是false,即顺时针
    ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);
    ctx.clip(); //画了圆 再剪切  原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
    ctx.drawImage(result[0], avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); // 推进去图片 

④ 在背景图上画

ctx.drawImage('小程序码的本地地址', x轴, Y轴, 宽, 高)

最终绘制完把canvas画布转成图片并返回图片地址

        wx.canvasToTempFilePath({
           canvasId: 'myCanvas',
           success: function (res) {
             canvasToTempFilePath = res.tempFilePath // 返回的图片地址保存到一个全局变量里
             that.setData({
               showShareImg: true
             })
             wx.showToast({
               title: '绘制成功',
             })
           },
           fail: function () {
             wx.showToast({
               title: '绘制失败',
             })
           },
           complete: function () {
             wx.hideLoading()
             wx.hideToast()
           }
         })

如果直接按照上面这样写会出现空白图片,解决方法如下

 ctx.draw(
                     setTimeout(() => {
                        wx.canvasToTempFilePath({
                           canvasId: 'myCanvas',
                           success: (res) => {
                              // 返回的图片地址保存到一个全局变量里
                              than.setData({
                                 canvasToTempFilePath: res.tempFilePath
                              })
                           },
                           complete: () => {
                              this.setData({
                                 states: !this.data.states
                              })
                           }
                        })
                     }, 500),
                  );

⑤最终绘制完把canvas画布转成图片并返回图片地址
// 获取用户是否开启用户授权相册
    if (!openStatus) {
      wx.openSetting({
        success: (result) => {
          if (result) {
            if (result.authSetting["scope.writePhotosAlbum"] === true) {
              openStatus = true;
              wx.saveImageToPhotosAlbum({
                filePath: canvasToTempFilePath,
                success() {
                  that.setData({
                    showShareImg: false
                  })
                  wx.showToast({
                    title: '图片保存成功,快去分享到朋友圈吧~',
                    icon: 'none',
                    duration: 2000
                  })
                },
                fail() {
                  wx.showToast({
                    title: '保存失败',
                    icon: 'none'
                  })
                }
              })
            }
          }
        },
        fail: () => { },
        complete: () => { }
      });
    } else {
      wx.getSetting({
        success(res) {
          // 如果没有则获取授权
          if (!res.authSetting['scope.writePhotosAlbum']) {
            wx.authorize({
              scope: 'scope.writePhotosAlbum',
              success() {
                openStatus = true
                wx.saveImageToPhotosAlbum({
                  filePath: canvasToTempFilePath,
                  success() {
                    that.setData({
                      showShareImg: false
                    })
                    wx.showToast({
                      title: '图片保存成功,快去分享到朋友圈吧~',
                      icon: 'none',
                      duration: 2000
                    })
                  },
                  fail() {
                    wx.showToast({
                      title: '保存失败',
                      icon: 'none'
                    })
                  }
                })
              },
              fail() {
                // 如果用户拒绝过或没有授权,则再次打开授权窗口
                openStatus = false
                console.log('请设置允许访问相册')
                wx.showToast({
                  title: '请设置允许访问相册',
                  icon: 'none'
                })
              }
            })
          } else {
            // 有则直接保存
            openStatus = true
            wx.saveImageToPhotosAlbum({
              filePath: canvasToTempFilePath,
              success() {
                that.setData({
                  showShareImg: false
                })
                wx.showToast({
                  title: '图片保存成功,快去分享到朋友圈吧~',
                  icon: 'none',
                  duration: 2000
                })
              },
              fail() {
                wx.showToast({
                  title: '保存失败',
                  icon: 'none'
                })
              }
            })
          }
        },
        fail(err) {
          console.log(err)
        }
      })
    }



原文:小程序如何生成海报分享朋友圈:https://segmentfault.com/a/1190000019083548
作者:小白