【UniApp实战分享】UniApp图片处理功能实现指南

以下是优化后的技术文档,主要从结构清晰度语言精炼度代码注释规范读者认知路径四个维度进行优化:


UniApp图片处理功能实现指南

一、核心API说明

API功能描述官方文档链接
uni.chooseImage从相册或相机选择图片查看文档
uni.compressImage压缩图片文件查看文档

二、功能实现详解

1. 图片选择功能

实现逻辑
通过 uni.chooseImage 调用微信小程序的图片选择能力,限定以下参数:

  • count:1:单次仅选择1张图片
  • sizeType:["compressed"]:优先返回压缩后图片

代码实现

/**
 * 选择图片并返回临时文件路径
 * @returns {Promise<string>} 图片临时路径
 */
const chooseImage = (): Promise<string> => {
  return new Promise((resolve, reject) => {
    uni.chooseImage({
      count: 1,
      sizeType: ["compressed"],
      success: (res: { tempFiles: { path: string }[] }) => {
        resolve(res.tempFiles[0].path);
      },
      fail: () => reject("图片选择失败")
    });
  });
};

2. 图片压缩功能

参数说明

参数名类型说明
pathstring待压缩图片路径
maxSizenumber压缩后最大文件大小(单位:Byte)
qualitynumber初始压缩质量(默认100,范围1-100)

实现亮点

  • 递归压缩:若压缩后文件仍超限,按5%递减质量直至达标
  • Base64转换:通过 uni.getFileSystemManager 将压缩结果转为Base64格式
/**
 * 递归压缩图片直至满足大小限制
 * @param path - 图片路径
 * @param maxSize - 目标最大字节数
 * @param quality - 压缩质量(默认100)
 */
const compressImage = (
  path: string,
  maxSize: number,
  quality: number = 100
): Promise<string> => {
  return new Promise((resolve, reject) => {
    if (quality <= 0) reject(`图片无法压缩至${maxSize}B以下`);

    uni.compressImage({
      src: path,
      quality,
      compressedWidth: 200,  // 限制压缩后宽高,可能会导致图片被拉抻
      compressedHeight: 200,
      success: (res) => {
        const fs = uni.getFileSystemManager();
        const base64 = `data:image/png;base64,${fs.readFileSync(res.tempFilePath, 'base64')}`;
        
        // 递归检查文件大小
        getStringByteSize(base64) > maxSize 
          ? compressImage(path, maxSize, quality - 5).then(resolve).catch(reject)
          : resolve(base64);
      },
      fail: () => reject("压缩失败")
    });
  });
};

3. 字符串字节数计算

背景说明
因微信小程序环境不支持Blob API,需手动实现字节数计算逻辑。

实现原理
根据Unicode编码范围判断字符占用字节数:

  • 0x0000-0x007F → 1字节
  • 0x0080-0x07FF → 2字节
  • 0x0800-0xFFFF → 3字节
  • 其他 → 4字节
/**
 * 计算字符串的字节大小
 * @param str - 待计算字符串
 * @returns {number} 字节数
 */
const getStringByteSize = (str: string): number => {
  return [...str].reduce((size, char) => {
    const code = char.charCodeAt(0);
    return size + (
      code <= 0x7f ? 1 :
      code <= 0x7ff ? 2 :
      code <= 0xffff ? 3 : 4
    );
  }, 0);
};

三、使用示例

// 完整调用流程
chooseImage()
  .then(path => compressImage(path, 1024*100)) // 压缩至100KB以内
  .then(base64 => console.log("压缩结果:", base64))
  .catch(err => console.error("处理失败:", err));

四、注意事项

  1. 性能优化:递归压缩需设置终止条件(示例中quality > 0
  2. 格式限制:当前实现固定输出PNG格式Base64,需根据实际需求调整
  3. 平台差异uni.getFileSystemManager 为微信小程序特有API
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值