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啦!

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大1 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师1 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学1 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端