vue2+elementui使用compressorjs压缩上传的图片

该文章已生成可运行项目,

代码中红色部分代表压缩多次只到达到我们预期的大小,但是不知道为什么只有第一次压缩有效。后面即使把压缩质量降低也没办法达到。所以就注释掉了这块的代码 

首先是npm install compressorjs

然后新建一个compressorjs.js的文件

import Compressor from "compressorjs";

// 默认压缩配置
const DEFAULT_COMPRESS_OPTIONS = {
  quality: 0.6, // 默认压缩质量 (0-1)
  maxWidth: 1920, // 最大宽度
  maxHeight: 1080, // 最大高度
  convertSize: Infinity, // 禁用自动转换为WebP
};
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB

/**
 * 压缩图片文件
 * @param {File} file - 待压缩的图片文件
 * @param {Object} options - 压缩配置项
 * @returns {Promise<File>} 压缩后的文件
 */
export function compressImage(file, options = {}, attempt = 1) {
  return new Promise((resolve, reject) => {
// 压缩质量
    const currentQuality = Math.max(
        0.1,
        options.quality ?? DEFAULT_COMPRESS_OPTIONS.quality
      );

    // 合并配置并限制最小压缩质量
    const mergedOptions = {
      ...DEFAULT_COMPRESS_OPTIONS,
      ...options,
      quality:currentQuality,
      maxWidth: Math.min(
        options.maxWidth ?? DEFAULT_COMPRESS_OPTIONS.maxWidth,
        8192
      ),
      maxHeight: Math.min(
        options.maxHeight ?? DEFAULT_COMPRESS_OPTIONS.maxHeight,
        8192
      ),
      convertSize: Infinity, // 禁用自动转换为WebP
    };

    // 执行压缩
    new Compressor(file, {
      ...mergedOptions,
      success(result) {
        const newFile = new File([result], file.name, { type: result.type });
        const newSizeMB = (newFile.size / 1024 / 1024).toFixed(2);
        console.log(`第${attempt}次压缩结果: ${newSizeMB}MB,质量: ${currentQuality}`);
        //,本来打算设置一个最小值。一次压缩不成功。多次压缩。但是测试发现压缩多次,也只有第一次有效。后面都一样,所以隐藏了这里就没有用多次循环了
        // 检测压缩有效性(小于5%变化视为无效)
        // if (newFile.size >= file.size * 0.95) {
        //   console.log(`压缩无效(变化<5%),终止递归`);
        //   resolve(newFile);
        // } else if (newFile.size > MAX_FILE_SIZE) {
        //   resolve(compressImage(newFile, options, attempt + 1)); // 注意传递原始options
        // } else {
          resolve(newFile);
        // }
      },
      error(err) {
        console.error("压缩失败,使用原文件:", err);
        resolve(file); // 失败时返回原文件
        // reject(err);
      },
    });
  });
}

具体的使用页面。只用在上传之前before-upload的函数中压缩就可以啦

<el-upload
  :before-upload="beforeUploadImg"
>
</el-upload>

import { compressImage } from "@/utils/imageCompress";

async beforeUploadImg(file) {
  const fileSize = file.size / 1024 / 1024;
  let types = ["image/jpeg", "image/jpg", "image/png", "application/pdf"];
  const isImageOrPDF = types.includes(file.type);
  if (!isImageOrPDF) {
    this.$message.error("上传图片只能是 JPG/JPEG/PNG/PDF 格式!");
    return false;
  }

  try {
    // 压缩图片(仅处理大于5MB的图片)。当前你也可以不加这个限制就是压缩所有上传的图片
    if (fileSize > 5) {
      const compressedFile = await compressImage(file, {
        quality: fileSize > 10 ? 0.7 : 1,
        maxHeight: Infinity, // 不限制高度
      });
      return compressedFile; // 返回压缩后的文件
    }
    return file;
  } catch (err) {
    if (fileSize > 5) {
      this.$message({
        message: "上传图片大小超过限制",
        type: "warning",
      });
      return false;
    }
    console.error("压缩失败:", err);
    return file; // 降级处理:上传原文件
  }

}

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值