小程序离屏canvas(createOffscreenCanvas)生成推广海报

小程序离屏canvas(createOffscreenCanvas)生成推广海报

离屏canvas调用wx.canvasToTempFilePath报错Failed to execute ‘drawImage’ on ‘CanvasRenderingContext2D’: The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)
开发者工具版本:稳定版1.05.2204180(windows)
调试基础库版本:2.24.0

网上查半天资料一直找不到原因,不知道是不是createOffscreenCanvas不支持wx.canvasToTempFilePath方法,官方文档也没有说明。所以现在是用base64方法来生成海报。
各位如果知道是什么原因,麻烦告知一下哈!

--------------------------------------------------------------- 分割线 ---------------------------------------------------------------

背景图片

背景图片

效果图

效果图

getPoster: async function (e) {
    let that = this
    //  文件管理
    let fs = wx.getFileSystemManager();
    try {
      //  判断文件是否存在,如果存在则直接显示图片
      fs.accessSync(`${wx.env.USER_DATA_PATH}/images/sharePoster.jpg`);
      this.setData({
        src: `${wx.env.USER_DATA_PATH}/images/sharePoster.jpg`
      })
      //  获取(缓存)背景图片的md5
      let sharePoster_md5 = wx.getStorageSync('sharePoster_md5');
      //  如果缓存不存在则重新生成海报
      if (!sharePoster_md5) {
        wx.showModal({
          title: "提示",
          content: "海报已更新,请重新生成!",
          showCancel: false,
          complete(res){
          //  删除缓存的图片
            fs.unlink({
              filePath: `${wx.env.USER_DATA_PATH}/images/sharePoster.jpg`,
              success(res) {
                console.log(res)
                //  重新调用该函数
                that.getPoster()
              },
              fail(res) {
                console.error(res)
              }
            })
          }
        })
      }else{
      //  背景图片的md5存在,请求后端对比服务器的背景图片的md5是否一致,如果不一致,则需要重新生成海报
        let md5 = await App.req.request('https://XXX.com/getSharePoster_md5.php', {md5: sharePoster_md5})
        if (md5.data !== 1) {
          wx.showModal({
            title: "提示",
            content: "海报已更新,请重新生成!",
            showCancel: false,
            complete(res){
              fs.unlink({
                filePath: `${wx.env.USER_DATA_PATH}/images/sharePoster.jpg`,
                success(res) {
                  console.log(res)
                  that.getPoster()
                },
                fail(res) {
                  console.error(res)
                }
              })
            }
          })
        }
      }
    } catch (e) {
    //	生成分享海报
      wx.showLoading({
        title: '正在生成分享码',
        mask: true
      })
      try {
        //  判断目录是否存在
        fs.accessSync(`${wx.env.USER_DATA_PATH}/images/`);
        console.log('目录存在');
      } catch (e) {
      //	目录不存在,创建目录
        try {
          fs.mkdirSync(`${wx.env.USER_DATA_PATH}/images/`, false)
          console.log("创建目录成功");
        } catch (error) {
          console.log("创建目录失败", error);
          wx.hideLoading();
          wx.showModal({
            title: "提示",
            content: "生成失败,请重试!",
            showCancel: false
          })
          throw false;
        }
      }
      //  请求后端生成小程序码(带参数)
      let img = await App.req.request('https:/XXX.com/getQRCode.php', {
        userId: App.data.userInfo.userId
      });
      img = img.data
      console.log("小程序码", img);
      // 获取背景图片信息(该接口会将图片加载到本地,但不会保存)
      let imageInfo = await App.wxp.getImageInfo({
        src: "https://XXX.com/sharePoster.jpg"
      });
      console.log("图片信息", imageInfo);
      //  判断生成小程序码和获取海报图片信息是否成功
      if (img.status === 1 && imageInfo.path) {
        //  创建离屏canvas
        let canvas = wx.createOffscreenCanvas({
          type: '2d',
          width: imageInfo.width,	//	canvas的宽度为"背景图片"的宽度
          height: imageInfo.height	//	canvas的高度为"背景图片"的高度
        });
        //  获取canvas上下文
        let context = canvas.getContext('2d')
        // 创建小程序码图片
        let QRCode = canvas.createImage();
        //  赋值图片地址
        QRCode.src = img.base64
        // 创建海报背景图片
        let sharePoster = canvas.createImage()
        sharePoster.src = imageInfo.path
        sharePoster.onload = e => {
          context.clearRect(0, 0, canvas.width, canvas.height);
          //  将背景图片绘制到canvas画布
          context.drawImage(sharePoster, 0, 0, imageInfo.width, imageInfo.height, 0, 0, imageInfo.width, imageInfo.height);
          //  将小程序码绘制到canvas画布(先绘制背景图片再绘制小程序码,所以小程序码会在背景图片上面)
		  // coordinateX,coordinateY是将小程序码绘制在背景图片的X坐标和Y坐标,坐标我是从后端传过来的,你们根据自己的背景图片来定这个坐标
          context.drawImage(QRCode, 0, 0, img.width, img.height, img.coordinateX, img.coordinateY, img.width, img.height)
          //  将canvas画布内容转base64
          let base64 = context.canvas.toDataURL('image/png');
          //  删除base64字符串的空格
          base64 = base64.replace('data:image/png;base64,', '');
          //  删除base64字符串的回车符和换行符
          base64 = base64.replace(/[\r\n]/g, '');
          try {
            //  将base64数据写入jpg文件(writeFile第一个参数是保存文件的路径,第二个参数是需要写入的数据,第三个参数是指定写入文件的编码,这里一定要用base64,这里一定要用base64,这里一定要用base64)
            fs.writeFileSync(`${wx.env.USER_DATA_PATH}/images/sharePoster.jpg`, base64, 'base64');
            //  没有报错,写入文件成功
            that.setData({
              src: `${wx.env.USER_DATA_PATH}/images/sharePoster.jpg`
            })
            
            //  获取背景图片的MD5值并存入缓存(用于判断当前海报的背景图片跟服务器的背景图片是否一致,如果则重新生成海报)
            fs.getFileInfo({
              filePath: imageInfo.path,
              complete(res){
                console.log("成功",res);
                if(res.digest){
                  wx.setStorage({
                    key: "sharePoster_md5",
                    data: res.digest
                  })
                }
              }
            })

          } catch (err) {
            console.log("生成失败",err);
            //  写入文件失败
            wx.showModal({
              title: "提示",
              content: "生成失败,请重试!",
              showCancel: false
            })
          }
          wx.hideLoading();
        }
      } else {
        //  生成小程序失败或获取图片信息失败
        wx.hideLoading();
        wx.showModal({
          title: "提示",
          content: "生成失败,请重试!",
          showCancel: false
        })
      }
    }
  },
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Null-滨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值