飞书小程序图片路径转成Base64或者file对象(基于Taro框架)

前言:小程序是基于客户端的原因,有轻巧的优势自然就会有许多限制,例如发起网络请求但是无法使用fetch等;本节主要讲述图片文件的处理,很多情况下获取手机的文件最后官方回返回一些几乎不可读的图片文件路径地址,当然这些图片的地址是可以展示的。

  • 型如:ttfile://temp/7ee57123-76c9-4d8a-9fb7-18141f62292a-0bd162d9f2d3572c67bb3f0fca49b82e63d0c368.jpeg
  • 但是很多情况下,我们需要用到 file 对象或者 Base64 ;或者上传到OSS服务器的时候,无法使用官方提供 put 的上传方案!!!
  • 核心就是使用官方的 FileSystemManager.readFile飞书说明链接

一、方法封装如下: getBase64ByFilePath ()

/**
 * 本地文件路径通过读取文件获取文件base64
 * @param filePath
 * @param size 文件大小,如 1024,非必填
 * @returns
 */
export const getBase64ByFilePath = async (filePath, size?) => {
    
    
  // 进行压缩, size 仅用于压缩
  const _filePath = await compressFile({
    
     path: filePath, size });
  return new Promise<GetBase64ByFilePathResult>((resolve, reject) => {
    
    
    const fileSystemManager = tt?.getFileSystemManager(); // 获取飞书文件管理,通过 readFile 读取文件,微信小程序同理 wx?.getFileSystemManager()
    if (!fileSystemManager) reject({
    
     base64Url: '', success: false });
    const fileType = _filePath?.split('.')?.pop(); // 主要是为了拼接 base64 Url,通过飞书文件路径,获取文件类型
    const fileName = _filePath?.split('-')?.pop(); // 主要是为了拼接 base64 Url,通过飞书文件路径,获取文件名称(模糊的名称,不算重要)
    fileSystemManager?.readFile({
    
    
      filePath: _filePath,
      encoding: 'base64',
      success(res) {
    
    
        const base64Url = `data:image/${
      
      fileType || 'jpeg'};base64,${
      
      res?.data}`;
        const result = {
    
     base64Url, fileName, fileType, success: true };
        resolve(result);
      },
      fail(res) {
    
    
        console.log(`readFile fail: ${
      
      JSON.stringify(res)}`);
        const result = {
    
     base64Url: '', fileName, fileType, success: false };
        reject(result);
      }
    });
  });
};

二、另外想了解图片压缩的,可以学习一下 compressFile(),另外对于 web 用 canvas 进行图片压缩的处理,详见 使用canvas进行图片压缩

/**
 * 图片压缩
 * @param path 小程序文件地址,如 ttfile://xxx/xx-xx-xx.jpeg
 * @param size 文件大小,如 1024
 * @param compressThreshold 压缩开始阈值,默认 3M
 * @param openCompress 是否开启压缩, 默认 true
 * @param pictureQuality 压缩比 0-100,越低图片质量越差, 默认 80
 * @returns
 */
export const compressFile = ({
    
    
  path,
  size = undefined,
  compressThreshold = 3,
  openCompress = true,
  pictureQuality = 80
}) => {
    
    
  return new Promise<string>(resolve => {
    
    
    if (!path) return resolve(path);
    //当开启图片压缩且图片大小大于等于压缩阈值,进行压缩
    let flag = openCompress;
    if (size) {
    
    
      const fileSize = size / 1024 / 1024;
      flag = openCompress && fileSize >= compressThreshold;
    }
    if (flag) {
    
    
      console.log('===> being compress <===');
      Taro.compressImage({
    
    
        src: path, // 图片路径
        quality: pictureQuality, // 压缩质量
        success: res => {
    
    
          console.log('===> success compress <===');
          resolve(res?.tempFilePath || path);
        },
        fail: () => {
    
    
          console.log('===> fail compress <===');
          resolve(path);
        }
      });
    } else {
    
    
      resolve(path);
    }
  });
};

最后:拓展

  1. base64转换为file类型,类似详情 base64、file和blob用JS进行互转的方法大全
/**
 * base64转换为file类型
 * 先将base64转换成blob,再将blob转换成file文件,此方法不存在浏览器不兼容问题
 * @param base64Url
 * @param filename
 * @returns
 */
export const base64UrlToFile = (base64Url, filename) => {
    
    
  // 1. 先将base64转换成blob
  const arr = base64Url.split(',');
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    
    
    u8arr[n] = bstr.charCodeAt(n);
  }
  // 2. 再将blob转换成file文件
  return new File([u8arr], filename, {
    
     type: mime });
};
  1. 从本地相册选择图片或使用相机拍照。【详情见Taro官方文档,此处仅作记录】
Taro.chooseImage({
    
    
  count: 1, // 默认9
  sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
  sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有,在H5浏览器端支持使用 `user` 和 `environment`分别指定为前后摄像头
  success: (res) => {
    
    
    // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
    var tempFilePaths = res.tempFilePaths
  }
  fail: (res) => {
    
    }
})
  1. Taro将本地资源上传到服务器。客户端发起一个 HTTPS POST 请求,其中 content-type 为 multipart/form-data。但是如果是用OSS 上传是使用 put 方法,那只能使用 Taro.request 发起网络请求【详情见Taro官方文档,此处仅作记录】
const uploadTask = Taro.uploadFile({
    
    
  url: 'https://example.weixin.qq.com/upload', //仅为示例,非真实的接口地址
  filePath: tempFilePaths[0],
  name: 'file',
  formData:{
    
    
    'user': 'test'
  },
  success: function (res){
    
    
    var data = res.data
    //do something
  }
})
uploadTask.progress((res) => {
    
    
  console.log('上传进度', res.progress)
  console.log('已经上传的数据长度', res.totalBytesSent)
  console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend)
})
uploadTask.abort() // 取消上传任务

猜你喜欢

转载自blog.csdn.net/yiguoxiaohai/article/details/129190275