小程序canvas绘制图片并保存

准备画布

canvas关闭后再次显示画布会失效,这是因为wx:if会在dom上删除画布,所以我们应使用display来控制画布的显示隐藏


    
      
      
    
    保存到手机相册
  

建立canvas绘图的上下文对象

const ctx = wx.createCanvasContext('myCanvas')

绘制

先绘制一个和画布等同大小的白色矩形作为底图

ctx.setFillStyle('#fff') //设置填充色
ctx.fillRect(0, 0, this.shiftSize(300), this.shiftSize(369))
ctx.draw()
ctx.save()//保存当前的绘图上下文。
ctx.beginPath()//开始创建一个路径

绘制文字

ctx.setFillStyle('#EB4E3F')
ctx.setFontSize(this.shiftSize(12))
ctx.fillText('啦啦啦', this.shiftSize(15), this.shiftSize(325))
ctx.draw(true)//参数为 true,则保留当前画布上的内容,否则画布前面的内容会被清空

绘制图片并裁剪为圆形

this.getHeadImgPath().then((res) => {
      ctx.save()//保存当前的绘图上下文。
      ctx.beginPath()//开始创建一个路径

      ctx.arc(this.shiftSize(40), this.shiftSize(35), this.shiftSize(25), 0, 2 * Math.PI)//画一个圆形裁剪区域
      ctx.setStrokeStyle('#999')
      ctx.stroke()
      ctx.clip()//裁剪
      ctx.drawImage(res, this.shiftSize(15), this.shiftSize(10), this.shiftSize(50), this.shiftSize(50))//绘制图片
      ctx.restore()
      // ctx.draw(true)
      this.getGoodsImgPath().then((res) => {
        ctx.save()//保存当前的绘图上下文。
        ctx.drawImage(res, this.shiftSize(0), this.shiftSize(71), this.shiftSize(300), this.shiftSize(168));//绘制图片
        ctx.restore()
        // ctx.draw(true)
        this.getQrCodePath().then((res) => {
          ctx.save()//保存当前的绘图上下文。
          ctx.drawImage(res, this.shiftSize(192), this.shiftSize(249), this.shiftSize(93), this.shiftSize(93))
          // ctx.draw(true)
          ctx.restore()
          ctx.draw()
        });
      });
    });

canvas绘制时网络图片会无法绘制,所以使用wx.getImageInfo()方法把网络图片加载到本地再进行绘制,这是一个异步的操作,所以我们用promise封装一下

getHeadImgPath:function(){
    return new Promise((success,fail)=>{
      if(this.data.header_img_path){
        success(this.data.header_img_path);
      }else{
        wx.getImageInfo({
          src: util.Api.getCanvasImg + app.globalData.userInfo.avatarUrl,
          success: res => {
            this.setData({
              header_img_path: res.path
            })
            success(res.path);
          },
          fail:res=>{
            fail(res);
          }
        })
      }
    });
  },
  getGoodsImgPath:function(){
    return new Promise((success, fail) => {
      if (this.data.goods_img_path) {
        success(this.data.goods_img_path);
      } else {
        wx.getImageInfo({
          src: this.data.goodsInfo.img_url,
          success: res => {
            this.setData({
              goods_img_path: res.path
            })
            success(res.path);
          },
          fail: res => {
            fail(res);
          }
        })
      }
    });
  },
  getQrCodePath: function () {
    return new Promise((success, fail) => {
      if (this.data.qr_code_path) {
        success(this.data.qr_code_path);
      } else {
        var app_img = util.Api.shareGoodsAppImg + '?app_uuid=' + app.globalData.app_uuid + '&openid=' + app.globalData.openid + '&goods_id=' + this.data.goodsInfo.id + '&shop_id=' + this.data.goodsInfo.shop_id
        wx.getImageInfo({
          src: app_img,
          success: res => {
            this.setData({
              qr_code_path: res.path
            })
            success(res.path);
          },
          fail: res => {
            fail(res);
          }
        })
      }
    });
  },

注:canvas画布的默认单位是px,所以我们需要换算一下单位

shiftSize: function (w) {
    if (this.data.windowV) {
      return w / this.data.windowV;
    }
    return w;
  },

保存绘制的图片到相册

saveCanvasImg(){
    wx.canvasToTempFilePath({//把当前画布指定区域的内容导出生成指定大小的图片
      canvasId: 'myCanvas',
      success(res) {
        wx.authorize({//向用户发起授权请求
          scope: 'scope.writePhotosAlbum',//保存相册授权
          success:()=>{
            wx.saveImageToPhotosAlbum({//保存图片到系统相册
              filePath: res.tempFilePath,
              success:()=>{
                wx.showToast({
                  title: '图片保存成功'
                })
              }
            })
          }
        })
      }
    })
  }

你可能感兴趣的:(小程序)