上传图片压缩

文章介绍了如何将Canvas生成的base64数据转换为File或Blob格式,以便进行图片压缩,然后处理上传至服务器。方法包括`dataURLtoFile`和`dataURLtoBlob`,以及一个名为`compressImg`的公共方法,用于压缩图片并根据不同格式返回文件。
// canvas生成的格式为base64,需要进行转化, base64->file
const dataURLtoFile = (dataurl,fileName)=> {
  let arr = dataurl.split(','),
      mime = arr[0].match(/:(.*?);/)[1],

      bstr = atob(arr[1]),
      n = bstr.length,
      u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], fileName, {type:mime})
}

// canvas生成的格式为base64,需要进行转化, base64->blob
const dataURLtoBlob = (dataurl)=> {
  const arr = dataurl.split(","),
      mime = arr[0].match(/:(.*?);/)[1],
      bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
}

/**

* @压缩公共方法

* @params file

* @return 压缩后的文件,支持两种,file和 blob

*/

const compressImg = (file,fileName)=> {
  return new Promise(resolve => {
    const reader = new FileReader();
    // readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE,并触发 loadend (en-US) 事件,
    // 同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。
    reader.readAsDataURL(file);
    reader.onload = () => {
      const img = new Image();
      img.src = reader.result;
      img.onload = () => {
        // 图片的宽高
        const w = img.width;
        const h = img.height;
        const canvas = document.createElement("canvas");
        // canvas对图片进行裁剪,这里设置为图片的原始尺寸
        canvas.width = w;
        canvas.height = h;
        const ctx = canvas.getContext("2d");
        // canvas中,png转jpg会变黑底,所以先给canvas铺一张白底
        ctx.fillStyle = "#fff";
        // fillRect()方法绘制一个填充了内容的矩形,这个矩形的开始点(左上点)在
        // (x, y) ,它的宽度和高度分别由width 和 height 确定,填充样式由当前的fillStyle 决定。
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        // 绘制图像
        ctx.drawImage(img, 0, 0, w, h);

        // canvas转图片达到图片压缩效果
        // 返回一个包含图片展示的 data URI base64 在指定图片格式为 image/jpeg 或 image/webp的情况下,
        // 可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
        const dataUrl = canvas.toDataURL("image/jpeg", 0.8);

        // base64格式文件转成Blob文件格式
        let blobFile = dataURLtoBlob(dataUrl);
        console.log("压缩后的图片:Blob文件----------");
        console.log(blobFile);
        // base64格式文件转成file文件格式
        // let fileName = this.sourceFile.name
        resolve(dataURLtoFile(dataUrl,fileName));
        console.log("压缩后的图片:file文件----------");
      };
    };
  })
}
const uploadAction= async (option)=>{
  const file = await compressImg(option.file,option.file.name)
  let formData = new FormData()
  formData.append('file',file)
  baseService.post('上传路径',formData).then(res=>{
    if (res.code !== 0) {
      return ElMessage.error(res.msg);
    }
    emit("update:modelValue", res.data.src);
    ElMessage.success({
      message: "上传成功"
    });
  }).catch(()=>{
    ElMessage.error({
      message: "上传失败"
    });
  })
}
<think> 首先,用户的问题是关于若依框架中上传图片时进行压缩的实现方法。用户参考了一些引用内容,包括实现zip上传和导出、集成X-File-Storage框架、以及图片压缩处理方法。 关键点: - 用户想查找在若依框架中上传图片时进行压缩的方法。 - 参考的引用涉及Java代码片段,特别是与图片上传压缩相关。 从引用中提取相关信息: - 引用1:提到了使用zip上传图片的实现,但没有明确说到压缩。 - 引用2:展示了如何集成X-File-Storage框架上传图片到阿里云OSS,但没有提到压缩。 - 引用3:直接提到了“基于java的图片压缩处理方法”,并提到“可供rouyi框架上传minio调用”,这更相关。具体代码是:`MultipartFile multipartFile = new MockMultipartFile("file", newFile.getName(), file.getContentType(), input);`。这表明有一个图片压缩的过程,但代码片段不完整,只显示了创建MultipartFile的部分。 用户要求实现方法,所以我需要提供在若依框架中上传图片时进行压缩的具体步骤和代码实现。 核心思想: - 图片压缩通常在服务端处理,在上传后对图片进行压缩,然后存储。 - 在若依框架中,这可以通过修改上传控制器或在服务层添加压缩逻辑来实现。 步骤: 1. **理解上传流程**:在若依框架中,图片上传通常通过`CommonController`中的`uploadFile`方法处理。 2. **添加压缩逻辑**:在上传文件之前或之后,添加一个步骤来压缩图片。 3. **使用Java库进行压缩**:可以使用如Thumbnailator、ImageIO或Java原生API来实现图片压缩。 基于引用3的提示,提供一个完整的示例。 实现方法: - 创建一个工具类来处理图片压缩。 - 在控制器中调用这个工具类。 代码示例: - 定义一个图片压缩工具类。 - 修改`CommonController`中的`uploadFile`方法,在保存文件前压缩图片。 详细步骤: 1. **添加依赖**:如果使用第三方库如Thumbnailator,需要在pom.xml中添加依赖。 2. **创建压缩工具类**:编写一个静态方法来压缩图片。 3. **在控制器中集成**:在文件上传方法中调用压缩方法。 确保使用中文回答,结构清晰。 最终回答结构: - 解释方法。 - 提供代码示例。 - 添加相关问题。 </think> 在若依框架中实现上传图片时的压缩功能,可以通过在服务端添加压缩逻辑来实现。核心思路是:在文件上传控制器中,对接收到的图片文件进行处理,使用Java图像处理库(如Thumbnailator或Java原生ImageIO)压缩图片后再存储或上传到云服务。以下基于引用[^3]中的提示(基于Java的图片压缩处理方法),结合若依框架的结构,提供详细实现步骤和代码示例。 ### 实现步骤 1. **添加依赖**:首先在项目中引入图片压缩库(推荐Thumbnailator,轻量且易用)。 2. **创建压缩工具类**:编写一个工具类处理图片压缩逻辑。 3. **修改上传控制器**:在若依的`CommonController`中调用压缩工具类,对上传图片进行压缩。 4. **处理压缩后的文件**:将压缩后的图片上传到存储服务(如MinIO、OSS或本地)。 ### 代码实现 以下代码基于若依框架的`ruoyi-admin`模块实现。假设框架已集成MinIO或其他存储服务(如引用[^2]中的阿里云OSS)。 #### 1. 添加Thumbnailator依赖 在`ruoyi-admin`模块的`pom.xml`中添加依赖: ```xml <dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</artifactId> <version>0.4.18</version> </dependency> ``` #### 2. 创建图片压缩工具类 在`com.ruoyi.common.utils`包下新建`ImageCompressUtil.java`: ```java import net.coobird.thumbnailator.Thumbnails; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayOutputStream; import java.io.IOException; public class ImageCompressUtil { /** * 压缩图片到指定质量(0.0-1.0,值越小压缩率越高) * * @param file 原始图片文件 * @param quality 压缩质量(建议0.5-0.8) * @return 压缩后的MultipartFile对象 */ public static MultipartFile compressImage(MultipartFile file, float quality) throws IOException { if (file.isEmpty() || !file.getContentType().startsWith("image/")) { return file; // 非图片文件直接返回 } // 使用Thumbnailator压缩图片 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); Thumbnails.of(file.getInputStream()) .scale(1.0) // 保持原始尺寸 .outputQuality(quality) // 设置压缩质量 .toOutputStream(outputStream); // 创建压缩后的MultipartFile(参考引用[^3]的MockMultipartFile实现) return new MockMultipartFile( file.getName(), file.getOriginalFilename(), file.getContentType(), outputStream.toByteArray() ); } } ``` #### 3. 修改上传控制器 在`com.ruoyi.web.controller.common.CommonController`中修改`uploadFile`方法,调用压缩工具类: ```java import com.ruoyi.common.utils.ImageCompressUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @RestController public class CommonController { @Autowired private FileStorageService fileStorageService; // 引用[^2]中的存储服务 /** * 通用上传请求(单个文件),添加图片压缩逻辑 */ @PostMapping("/upload") public AjaxResult uploadFile(MultipartFile file) throws Exception { try { // 检查是否为图片文件,并进行压缩(质量设为0.7,压缩率适中) if (file.getContentType().startsWith("image/")) { file = ImageCompressUtil.compressImage(file, 0.7f); } // 指定存储路径(如OSS或MinIO) String objectName = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "/"; FileInfo fileInfo = fileStorageService.of(file) .setPath(objectName) .upload(); // 上传压缩后的文件 // 返回结果 AjaxResult ajax = AjaxResult.success(); ajax.put("url", fileInfo.getUrl()); ajax.put("fileName", fileInfo.getFilename()); return ajax; } catch (Exception e) { return AjaxResult.error("图片压缩失败: " + e.getMessage()); } } } ``` ### 关键说明 - **压缩逻辑**:仅在文件类型为`image/*`时触发压缩(如JPG、PNG),避免对非图片文件误处理。 - **压缩质量**:`quality`参数(0.0-1.0)控制压缩率。值越低文件越小,但可能损失画质。建议根据需求调整(如0.7平衡质量和大小)。 - **存储集成**:压缩后调用`fileStorageService`上传(如引用[^2]的OSS集成)。若使用MinIO,需确保依赖已配置。 - **性能考虑**:压缩操作会增加服务器负载,建议对大文件异步处理或添加文件大小阈值(如仅压缩>1MB的图片)[^3]。 ### 注意事项 - **测试建议**:在开发环境测试压缩效果,调整`quality`值以达到最佳平衡。 - **错误处理**:添加日志记录压缩失败,避免影响正常上传流程。 - **扩展性**:若需支持zip包上传(如引用[^1]),可在`importExcelPic`方法中调用压缩工具类遍历图片文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值