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

使用场景

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

问题说明

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

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

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

  1. 不支持base64图片;
  2. 图片必须下载到本地后才能绘制到画布上;
  3. 图片域名需要在管理平台加入downFile安全域名;
  4. canvas属于原生组件,在移动端会置于最顶层;
  5. 通过SelectorQuery只能拿到节点的style,而无法获取文本节点的内容以及图片节点的链接。

解决方法

先把小程序码通过小程序API中的FileSystemManager.writeFile()接口写入本地并获取到一个临时URL。

示例代码:

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)
})

页面中进行使用:

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)
  })
}

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

// 删除存储的垃圾数据
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()
    }
  })
})
// 在页面调用方法
import { writeFile,removeSave } from '../../utils/wxFunc'
 
removeBeforeFiles () {
  removeSave()
},
 
getUseCode () {
  //codeUrl为base64格式的小程序码
  writeFile(code).then(img => { 
    console.log(`可使用的小程序码:${img}`) // img格式:http://usr/1599468897794share.png
  }).catch(e => {
    console.log(e);
  })
},
 

最后就accomplish啦!感谢

微信小程序中base64格式的小程序码通过canvas画出来无效_微信小程序 base64 图片太大 canvas 绘制不了-CSDN博客

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Uniapp是一款跨平台的开发工具,可以使用一套代码开发多个平台的应用程序,包括微信小程序。在Uniapp使用百度地图需要安装百度地图API插件,并在小程序app.vue文件进行配置。 具体步骤如下: 1. 在HBuilderX打开Uniapp项目,在manifest.json文件添加百度地图插件。可以在“插件”选项卡搜索“百度地图”并添加。 2. 在app.vue文件引入百度地图API,并在onLaunch生命周期函数进行初始化配置。代码示例如下: ``` import bmap from '@/static/js/bmap.js' export default { onLaunch: function () { // 初始化百度地图API var BMap = new bmap.BMapWX({ ak: 'your ak' // 这里需要替换成自己的百度地图AK }) this.globalData.BMap = BMap }, globalData: { userInfo: null, BMap: null } } ``` 3. 在需要使用百度地图的页面,引入并使用BMapWX实例进行调用。例如,在某个页面需要获取当前位置的经纬度,代码示例如下: ``` export default { data() { return { longitude: '', latitude: '' } }, mounted() { this.getLocation() }, methods: { getLocation() { var vm = this vm.$uni.showLoading({ title: '正在获取位置' }) vm.$uni.getLocation({ type: 'wgs84', success: function(res) { var BMap = getApp().globalData.BMap var location = res.longitude + ',' + res.latitude BMap.regeocoding({ location: location, success: function(res) { vm.longitude = res.originalData.result.location.lng vm.latitude = res.originalData.result.location.lat vm.$uni.hideLoading() }, fail: function() { vm.$uni.hideLoading() vm.$uni.showToast({ title: '获取位置失败', icon: 'none' }) } }) }, fail: function() { vm.$uni.hideLoading() vm.$uni.showToast({ title: '获取位置失败', icon: 'none' }) } }) } } } ``` 在以上示例,首先通过uni.getLocation()方法获取当前位置的经纬度,然后使用BMapWX实例的regeocoding方法将经纬度转换为地址信息,最后将地址信息的经纬度提取出来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值