uniap小程序中使用canavs绘制base64格式,真机调试二维码不显示的问题。

使用场景 小程序(vue3写法)中有一个这样的场景:一个图片(包括了背景图,二维码,标题),类似于zfb中的每天扫一扫,方便用户保存在本地。

问题说明

小程序码通过后台接口获取,格式如下:'data:image/jpg;base64,/9j/4AAQSkZJRgAB......'

通过canvas画出来之后,在微信开发者工具上有效,在真机上无效。

随后就踩上了这个坑,小程序的canvas局限性很多。主要体现在如下几点:

1.不支持base64图片;

2.图片必须下载到本地后才能绘制到画布上;

3.图片域名需要在管理平台加入downFile安全域名;

4.canvas属于原生组件,在移动端会置于最顶层;

5.通过SelectorQuery只能拿到节点的style,而无法获取文本节点的内容以及图片节点的链接。

解决方法:

先把小程序码通过小程序API中的FileSystemManager.writeFile()接口写入本地并获取到一个临时URL。首先在utils文件夹下创建一个文件
代码:

js 复制代码
export const writeFile = (base64Str) => new Promise((resolve, reject) => {
  // 后台返回的base64格式数据的回车换行换为空字符''
  const base64Image = base64Str.split(',')[1].replace(/[\r\n]/g, '')
  // 文件管理器
  const fsm = wx.getFileSystemManager()
  // 文件名
  const FILE_BASE_NAME = 'tmp_base64src'
  // 文件后缀
  const format = 'png'
  // 获取当前时间戳用于区分小程序码,防止多次写进的小程序码图片都一样,建议通过不同的列表ID来区分不同的小程序码
  const timestamp = (new Date()).getTime()
  // base转二进制
  const buffer = wx.base64ToArrayBuffer(base64Image)
  // 文件名
  const filePath = `${wx.env.USER_DATA_PATH}/${timestamp}share.${format}`
  // 写文件
  fsm.writeFile({
    filePath,
    data: buffer,
    encoding: 'binary',
    success () {
      // 读取图片
      wx.getImageInfo({
        src: filePath,
        success (res) {
          const img = res.path
          // 把需要画出来的图片的临时url暴露出去
          resolve(img)
          reject()
        },
        fail (e) {
          console.log('读取图片报错')
          console.log(e)
        },
        error (res) {
          console.log(res)
        }
      })
    },
    fail (e) {
      console.log(e)
    }
  })
}).catch((e) => {
  console.log(e)
})

页面中进行使用:

vue 复制代码
import { writeFile } from '../../utils/wxFunc'

const getUseCode = () => {
  //code为base64格式的小程序码
  writeFile(code).then((img) => {
    console.log(`可使用的小程序码:${img}`) // img格式:http://usr/1599468897794share.png
  }).catch((e) => {
    console.log(e)
  })
}

这样的缺点在于每调用一次写一个文件,文件会越写越多,当文件管理器中文件总大小超过最大限制则会报错。解决方法:在写入文件之前先做一次删除操作,可看到打印出的

这些是上次保留的图片,所以解决这个问题:
关键代码如下(utils创建的js下):

js 复制代码
// 删除存储的垃圾数据
export const removeSave = () => new Promise((resolve) => {
  // 文件管理器
  const fsm = wx.getFileSystemManager()
  // 获取文件列表
  fsm.readdir({
    dirPath: wx.env.USER_DATA_PATH, // 当时写入的文件夹
    success (res) {
      res.files.forEach((el) => { // 遍历文件列表里的数据
        // 删除存储的垃圾数据
        if (el !== 'miniprogramLog') { // 过滤掉miniprogramLog
          fsm.unlink({
            filePath: `${wx.env.USER_DATA_PATH}/${el}`, // 文件夹也要加上,如果直接文件名会无法找到这个文件
            fail (e) {
              console.log('readdir文件删除失败:', e)
            }
          })
        }
      })
      resolve()
    }
  })
})
vue 复制代码
// 在页面调用方法
import {onUnmounted} from 'ref'
import { writeFile,removeSave } from '../../utils/wxFunc'
 
//卸载的时候去操作
onUnmounted(() => {
  removeSave().then(() => {
    getUseCode()
  }).catch((e) => {
    console.log(e)
  })
})

最后就accomplish啦!

相关推荐
辻戋2 小时前
从零实现React Scheduler调度器
前端·react.js·前端框架
徐同保2 小时前
使用yarn@4.6.0装包,项目是react+vite搭建的,项目无法启动,报错:
前端·react.js·前端框架
Qrun3 小时前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp3 小时前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.4 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl6 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫7 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友7 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理9 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻9 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js