安卓不管是压缩和不压缩分享要微信都很糊 uni-app

安卓不管是压缩和不压缩分享要微信都很糊 uni-app 产品分类:uniapp/App
PC开发环境操作系统:Mac
PC开发环境操作系统版本号:15.1 (24B83)
HBuilderX类型:正式
HBuilderX版本号:4.85
手机系统:Android
手机系统版本号:Android 15
手机厂商:vivo
手机机型:一加 ACE5:PLF110
页面类型:vue
vue版本:vue3
打包方式:云端
项目创建方式:HBuilderX


示例代码:

export const compressPic = (url: string): Promise<string> => {
return new Promise((resolve) => {
const sys = uni.getSystemInfoSync();
const isAndroid = sys.platform === "android";
// 目标大小区间 (KB)
const MIN_SIZE = 10;
const MAX_SIZE = isAndroid ? 100 : 20;
// 最大重试次数,防止死循环
const MAX_RETRIES = 6;

if (!url) {
  resolve(DEFAULT_SHARE_IMG);
  return;
}

if (isAndroid) {
  resolve(url);
  return;
}
// 获取文件大小 (KB)
const getFileSize = (filePath: string): Promise<number> => {
  return new Promise((res) => {
    uni.getFileInfo({
      filePath,
      success: (info) => {
        res(info.size / 1024);
      },
      fail: () => {
        res(0);
      },
    });
  });
};

// 递归压缩核心逻辑
const recursiveCompress = (
  src: string,
  currentWidth: number,
  currentQuality: number,
  retryCount: number
) => {
  // 超过最大重试次数,如果还是太大,直接返回兜底图,避免分享失败
  if (retryCount > MAX_RETRIES) {
    console.warn(`压缩次数过多,放弃压缩,使用兜底图`);
    resolve(DEFAULT_SHARE_IMG);
    return;
  }

  console.log(
    `第 ${retryCount + 1} 次压缩: 宽 ${currentWidth}, 质量 ${currentQuality}`
  );

  uni.compressImage({
    src,
    quality: currentQuality,
    compressedWidth: currentWidth,
    success: async (res) => {
      const tempPath = res.tempFilePath;
      const size = await getFileSize(tempPath);
      console.log(`当前体积: ${size.toFixed(2)}KB`);

      if (size <= MAX_SIZE) {
        // 1. 完美:小于 20KB
        if (size >= MIN_SIZE) {
          console.log("压缩完美达标");
          resolve(tempPath);
        } else {
          // 2. 有点太小了(小于10KB),但也接受,毕竟越小越好,直接返回
          console.log("压缩结果小于10KB,直接使用");
          resolve(tempPath);
        }
      } else {
        // 3. 还是太大 (> 20KB),继续压缩
        // 策略:优先降质量,质量太低了再降尺寸
        let nextQuality = currentQuality;
        let nextWidth = currentWidth;
        nextQuality = currentQuality - 15;
        if (nextQuality < 30) {
          nextQuality = 50; // 重置质量
          nextWidth = Math.floor(currentWidth * 0.8); // 尺寸缩小20%
        }
        if (nextWidth < 200) nextWidth = 200;
        // 递归调用
        recursiveCompress(
          isAndroid ? src : tempPath,
          nextWidth,
          nextQuality,
          retryCount + 1
        );
      }
    },
    fail: (err) => {
      console.error("压缩API失败", err);
      resolve(DEFAULT_SHARE_IMG);
    },
  });
};

// 初始入口
const startCompress = (src: string) => {
  getFileSize(src).then((size) => {
    console.log(`【Debug】原始图片体积: ${size.toFixed(2)}KB`);
  });
  uni.getImageInfo({
    src,
    success: (imageInfo) => {
      // 初始策略:基准宽度 300px,初始质量 80
      const baseWidth = 300;
      const baseQuality = isAndroid ? 92 : 80;

      const startWidth =
        imageInfo.width > baseWidth ? baseWidth : imageInfo.width;
      recursiveCompress(src, startWidth, baseQuality, 0);
    },
    fail: () => {
      resolve(DEFAULT_SHARE_IMG);
    },
  });
};

// 下载或直接处理
if (url.startsWith("http") || url.startsWith("https")) {
  uni.downloadFile({
    url,
    success: (res) => {
      if (res.statusCode === 200) {
        startCompress(res.tempFilePath);
      } else {
        resolve(DEFAULT_SHARE_IMG);
      }
    },
    fail: () => {
      resolve(DEFAULT_SHARE_IMG);
    },
  });
} else {
  startCompress(url);
}
});
};

更多关于安卓不管是压缩和不压缩分享要微信都很糊 uni-app的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

这是一个常见的Android平台微信分享图片模糊问题,主要原因是:
Android系统对图片路径访问权限限制,建议使用uni.chooseImage选择相册原图路径 微信对Android平台图片有额外的压缩处理
解决方案:

确保使用绝对路径(如uni.chooseImage返回的tempFilePath)

分享前使用canvas对图片进行预压缩处理

如仍不满足,推荐使用UTS插件实现原生分享:分享插件

参考文档:分享API

建议先检查图片路径是否来自相册选择,并尝试使用UTS插件方案解决兼容性问题。

内容为 AI 生成,仅供参考

更多关于安卓不管是压缩和不压缩分享要微信都很糊 uni-app的实战教程也可以访问 https://www.itying.com/category-93-b0.html


图片是网络图 不是选择的

该bug反馈内容较完整,包含标题、详细描述、代码示例、复现步骤等要素,但存在以下问题:

描述可补充:未说明测试图片原始分辨率/大小,且"很糊"缺乏量化标准(如具体模糊程度、对比图)。
复现步骤不足:仅说明"直接调用压缩分享糊",但未提供完整分享API调用代码(如uni.share参数配置),官方难以精准复现。
版本问题:用户使用HBuilderX 4.85(2024年版本),而知识库显示最新正式版已修复多起Android图像问题,建议升级至4.86+版本验证。
核心误区:

Android高版本(尤其Android 15预览版)存在文件权限限制,直接返回原图路径可能导致微信无法访问私有目录,从而使用低清缩略图。
代码中Android直接跳过压缩(resolve(url))不合理,应参照iOS逻辑处理,但需适配Android路径规范。

解决方案建议:

升级HBuilderX至最新版(知识库提及Android平台持续优化图像API)。
Android分享前需将图片保存至公共目录(如/sdcard/DCIM/),参考uts分享插件方案。
调整压缩策略:Android需更高分辨率(建议宽度≥720px),避免微信二次压缩导致模糊。

此问题非纯uni-app bug,主要源于Android系统权限机制与微信分享策略差异,需结合平台特性调整实现。 内容为 AI 生成,仅供参考

这是一个典型的安卓平台图片压缩与分享清晰度问题。核心原因在于你的代码逻辑对安卓平台做了特殊处理:

  1. 关键问题:代码中第9行 if (isAndroid) { resolve(url); return; } 直接跳过了安卓的压缩流程,导致原始大图直接分享到微信。

  2. 微信分享限制:微信对分享图片有严格的体积限制(通常建议32KB以内),过大的图片会被微信服务器二次压缩,导致严重模糊。

  3. 安卓平台差异:虽然你设置了安卓的MAX_SIZE为100KB,但由于上述代码逻辑,这个设置从未生效。

解决方案

// 移除对安卓的特殊跳过逻辑
// if (isAndroid) {
//   resolve(url);
//   return;
// }

// 统一压缩策略,调整安卓参数
const MAX_SIZE = 32; // 统一设置为32KB,符合微信最佳实践
const baseQuality = 85; // 统一质量参数

// 调整压缩策略,避免过度压缩
const recursiveCompress = (src, currentWidth, currentQuality, retryCount) => {
  // ... 保持原有逻辑,但调整参数
  // 建议:质量每次降低10%,宽度每次降低10%
  let nextQuality = Math.max(30, currentQuality - 10);
  let nextWidth = Math.max(200, Math.floor(currentWidth * 0.9));
};
回到顶部