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

news/2024/7/20 0:48:13 标签: 小程序, javascript, 前端, html

html" title=小程序>小程序离屏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方法来生成海报。
各位如果知道是什么原因,麻烦告知一下哈!

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

背景图片

背景图片

效果图

效果图

html" title=javascript>javascript">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;
        }
      }
      //  请求后端生成html" title=小程序>小程序码(带参数)
      let img = await App.req.request('https:/XXX.com/getQRCode.php', {
        userId: App.data.userInfo.userId
      });
      img = img.data
      console.log("html" title=小程序>小程序码", img);
      // 获取背景图片信息(该接口会将图片加载到本地,但不会保存)
      let imageInfo = await App.wxp.getImageInfo({
        src: "https://XXX.com/sharePoster.jpg"
      });
      console.log("图片信息", imageInfo);
      //  判断生成html" title=小程序>小程序码和获取海报图片信息是否成功
      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')
        // 创建html" title=小程序>小程序码图片
        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);
          //  将html" title=小程序>小程序码绘制到canvas画布(先绘制背景图片再绘制html" title=小程序>小程序码,所以html" title=小程序>小程序码会在背景图片上面)
		  // coordinateX,coordinateY是将html" title=小程序>小程序码绘制在背景图片的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 {
        //  生成html" title=小程序>小程序失败或获取图片信息失败
        wx.hideLoading();
        wx.showModal({
          title: "提示",
          content: "生成失败,请重试!",
          showCancel: false
        })
      }
    }
  },

http://www.niftyadmin.cn/n/1162272.html

相关文章

Spring In Action 学习笔记(三) AOP

个人学习Spring In Action学习笔记系列 (三) AOP 源码地址 https://github.com/spring-projects/spring-framework U4 通知Bean 4.1 AOP简介 切面有助于实现交叉事务的模块化,每个模块是为特定领域提供服务,比如日志和安全就是一个交叉事务。 在面向切…

js歌词逐字滚动效果

js歌词逐字滚动效果 Null - 滨 先上效果图 目录结构&#xff1a; 歌词文本music.txt 将酷狗歌词KRC用“酷狗歌词(krc)加解密工具”进行解密后可以得到这种歌词文本 HTML代码 <!DOCTYPE html> <html lang"en"> <head><!-- 网页图标 --&g…

微信公众号(测试号)消息模板推送

微信公众号(测试号)消息模板推送 源码地址 https://github.com/panjianlong13/Weixin-PushMessage 微信测试号配置 登录到微信公众平台接口测试账号申请URL&#xff0c;微信扫码登录 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?tsandbox/login 登录后进入到测试号管理…

自己造轮子 DuDuMall(一) 项目架构设计

自己造轮子 DuDuMall 项目架构设计 源码地址 https://github.com/panjianlong13/DuDuMall_BackEnd SpringCloud全家桶商城网站&#xff0c;没想到啥好名字&#xff0c;暂时就用我女儿的小名好了。 第一阶段&#xff1a; 前端:首页页面后端:认证中心 商品微服务 购物车微服务…

DuDuMall(二) 基础架构搭建

自己造轮子 DuDuMall 基础架构搭建 源码地址 https://github.com/panjianlong13/DuDuMall_BackEnd 找台可以用的Linux Server作为开发环境&#xff0c;安装好Dokcer(废话就不多说了)&#xff0c;为了实现后期一键化容器部署的目标&#xff0c;这里的中间件尽量使用容器实现 M…

DuDuMall(三) 后端基础微服务

自己造轮子 DuDuMall 后端基础微服务 源码地址 https://github.com/panjianlong13/DuDuMall_BackEnd 本节针对系统后端业务微服务进行开发&#xff0c;以用户微服务为例子&#xff0c;实现了基本的API 新建项目 1.Create Project 2.更新pom.xml 引入需要的包 3.加入Swagger2…

DuDuMall(五) 项目自动化DevOps(基于Jenkins Docker)

自己造轮子 项目自动化DevOps(基于Jenkins,Docker) 源码地址 https://github.com/panjianlong13/DuDuMall_BackEnd 安装部署Jenkins 两种方式 1.普通方式&#xff08;此处不再赘述&#xff09; https://blog.csdn.net/zjh_746140129/article/details/80835866 2.容器方式 …

Django学习 (一) 简介 环境搭建

简介 Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。Django 是使用 Python 编写的一个开源 Web 框架&#xff0c;可以用它来快速搭建一个高性能的网站。 Django的MTV模型组织 Django是一个基于MVC构造的框架。但…