首页 APP开发 正文内容

uni-app 图片转 base64 时报错:uni.getFileSystemManager is not a function,附正确代码示例

2023年08月22日 , , , 494

图片转 base64 格式不要用老方法了,会报错的,这篇文章分享两个正确的实现方案。

问题描述

使用 uni-app 来开发安卓 APP 时,图片上传阿里云 OSS 时,需要将图片转成 base64 字符串格式才能上传,查询 uni-app 官方有个 uni.getFileSystemManager 的用法可以直接转,但运行时报错了,我的代码如下:

uni.getFileSystemManager().readFile({
    filePath: imagePath, // 这个是选择图片后返回的图片路径
    encoding: 'base64',
    success: res => {
      let base64 = res.data;
      console.log(base64);
    },
    fail: (e) => {
      console.log("图片转换失败:",e);
    }
  })

控制台报错信息:

uni.getFileSystemManager is not a function.

报错原因分析

uni.getFileSystemManager 是早期 uni-app 提供的 api,现在官方貌似找不到这个用法了,查询了一下,发现这个 api 只能在微信小程序上生效,在 APP 上是没有这个用法的,所以报错没有这个方法。

图片转 base64 格式
图片转 base64 格式

解决方法

既然是 APP 端运行,uni-app 文档里也没有能直接转换的 api,那就只好看看 html5plus了,找了一下,果然有方法。

APP 端图片转 base64 正确代码示例

plus.io.resolveLocalFileSystemURL(imagePath, (entry) => {
    entry.file((file) => {
      let fileReader = new plus.io.FileReader();
      fileReader.onloadend = (e) => {
        console.log(e.target.result) // 这里得到base64字符串
      };
      fileReader.readAsDataURL(file);
    })
  })

不得感叹一下,虽然 html5plus 目前已经停止维护了,但发挥的作用还是很大,很 APP 很难解决的问题,使用 plus 都能解决,当年开发 html5plus 真是功德无量。

终极简单解决方案

本以为使用 plus api 是比较简单的方法了,逛了一下论坛我又发现了一个 js 工具库,名字叫 image-tools,可谓最简单的方法、最少的代码实现这个功能:

  • api 简单:就两个 api,用法很简单;
  • 用法优雅:支持 Promise 调用;
  • 跨端支持:APP、微信小程序和 H5 都可以用。

具体用法

image-tools 是一个工具库,也是 uni-app 插件,可以在 uni-app 插件市场导入 HBuilderX,不过我不太喜欢这种方式,因为看着方便,但不知道会对文件目录做什么改动,之前出现过问题,再也不敢直接导入了。用 npm 安装指令如下:

npm i image-tools --save

在项目中使用:

import { pathToBase64, base64ToPath } from 'image-tools'

// 图片文件转base64
pathToBase64(path)
  .then(base64 => {
    console.log(base64) // 得到 base64 字符串
  })
  .catch(err => {
    console.error(err)
  })

// base64图片保存为文件
base64ToPath(base64)
  .then(path => {
    console.log(path)
  })
  .catch(err => {
    console.error(err)
  })

用法很简单,代码非常少。需要注意的是 path 参数是本地路径, uni-app、微信小程序使用的路径不支持网络路径,如果是网络图片要先下载下来,然后获取本地路径后再传入。

由于封装了 Promise,对于多个图片,还可以用 Promise.all 来处理多张图片上传:

Promise.all(imgPaths.map(path => pathToBase64(path)))
  .then(res => {
    console.log(res)
    // 得到所有图片的base64
    // [base64, base64...]
  })
  .catch(err => {
    console.error(err)
  })

这就是 uni-app 图片转 base64 格式的终极解决方法了,如果还有更好的方案,欢迎交流。