java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot压缩图片

SpringBoot压缩png, jpg, jpeg, webp类型图片的实现代码

作者:三过食堂而不入

这篇文章主要介绍了SpringBoot压缩png, jpg, jpeg, webp类型图片的实现,文中通过代码示例和图文结合的方式给大家讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下

1.需求

业务要求对png, jpg, jpeg, webp 格式图片进行等比例压缩

2.开发中遇到的问题

使用 Thumbnails 包, 发现只能压缩 jpg 和 jpeg , 不能压缩webp
接着找到了 webp-imageio 解决webp , 又发现 这俩都不支持 png ,
接着找到了 OpenViewerFX 去处理png…

3. 实现代码

3.1 pom 引用

  <!--压缩png-->
        <dependency>
            <groupId>org.jpedal</groupId>
            <artifactId>OpenViewerFX</artifactId>
            <version>6.6.14</version>
        </dependency>

        <!-- Thumbnailator: 图片缩放和压缩工具 -->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.14</version>
        </dependency>

        <!-- TwelveMonkeys: 支持更多图片格式 -->
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-core</artifactId>
            <version>3.9.4</version>
        </dependency>
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-jpeg</artifactId>
            <version>3.9.4</version>
        </dependency>
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-webp</artifactId>
            <version>3.9.4</version>
        </dependency>

        <!--压缩webp-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-imaging</artifactId>
            <version>1.0-alpha1</version>
        </dependency>
        <dependency>
            <groupId>org.sejda.imageio</groupId>
            <artifactId>webp-imageio</artifactId>
            <version>0.1.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.imgscalr/imgscalr-lib -->
        <dependency>
            <groupId>org.imgscalr</groupId>
            <artifactId>imgscalr-lib</artifactId>
            <version>4.2</version>
        </dependency>

3.2 controller 代码

我这里自己定死了生产图片文件夹的路径 , 各位大神按照自己实际的需求改动

package com.example.controller;

import com.example.service.ImageCompressionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;

/**
 * @ClassName: ImageCompressionController
 * @Description: TODO
 * @Author: 赵狗
 * @Date: 2024/8/23 15:04
 */
@RequestMapping("/imageApi")
@RestController
public class ImageCompressionController {
    @Autowired
    private ImageCompressionService imageCompressionService;

    /**
     * 图片压缩方法
     * @param file
     * @param quality
     * @return
     * @throws IOException
     */
    @PostMapping("/compressBySize")
    public String compressImageBySize(@RequestParam("file") MultipartFile file,
                                      @RequestParam("quality") String quality
                                      ) throws IOException {

        String outputPath = "F:\\images\\" + "compressed_size_" + file.getOriginalFilename();

        File outputFile = new File(outputPath);
        prepareOutputDirectory(outputFile);
        File inputFile = convertMultipartFileToFile(file);
        // 将quality转为 float
        float qualityFloat = Float.parseFloat(quality);

        imageCompressionService.compressImageBySize(inputFile, outputFile,qualityFloat);

        inputFile.delete();

        return "File compressed successfully by size: " + outputFile.getAbsolutePath();
    }

    /**
     * 判断文件夹是否存在, 如果没有则创建
     * @param outputFile
     */
    private void prepareOutputDirectory(File outputFile) {
        if (!outputFile.getParentFile().exists()) {
            outputFile.getParentFile().mkdirs();
        }
    }

    /**
     * 将MultipartFile转换为File
     * @param file
     * @return
     * @throws IOException
     */
    private File convertMultipartFileToFile(MultipartFile file) throws IOException {
        File convFile = new File(System.getProperty("java.io.tmpdir") + "/" + file.getOriginalFilename());
        file.transferTo(convFile);
        return convFile;
    }

    public boolean isWebPSupported() {
        Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("webp");
        return readers.hasNext();
    }

}

3.3 Service 代码

package com.example.service;

import com.idrsolutions.image.png.PngCompressor;
import com.luciad.imageio.webp.WebPWriteParam;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.stereotype.Service;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;

/**
 * @ClassName: ImageCompressionService
 * @Description: TODO
 * @Author: 赵狗
 * @Date: 2024/8/23 15:03
 */
@Service
public class ImageCompressionService {

    private static final int DEFAULT_QUALITY = 80; // 默认压缩质量为 80

    /**
     * 压缩图片方法
     * @param inputFile
     * @param outputFile
     * @param quality
     * @throws IOException
     */
    public void compressImageBySize(File inputFile, File outputFile, float quality) throws IOException {

        // 根据输入文件的后缀名获取文件格式
        String formatName = getFileExtension(inputFile);

        // 根据不同的文件格式,调用相应的压缩方法
        if ("webp".equalsIgnoreCase(formatName)) {
            // 对webp格式的图片进行压缩
            compressWebpImage(inputFile,outputFile,quality);
        } else if("png".equalsIgnoreCase(formatName)){
            // 对png格式的图片进行压缩
            compressPngImage(inputFile, outputFile);
        } else {
            // 对jpg或其他格式的图片进行压缩,这里假设jpg的压缩方法与其他格式不同
            compressJpgImage(inputFile, outputFile, quality, formatName);
        }
    }

    /**
     * 压缩jpg 以及 jpeg 格式的图片方法
     * @param inputFile
     * @param outputFile
     * @param quality
     * @param formatName
     * @throws IOException
     */
    private void compressJpgImage(File inputFile, File outputFile, float quality, String formatName) throws IOException {
        // 压缩jpg 以及 jpeg 格式的图片
        Thumbnails.of(inputFile)
                .scale(1) // 明确告诉库不需要改变图片尺寸
                .outputQuality(quality) // 设置输出图片的质量
                .outputFormat(formatName) // 保持原有格式
                .toFile(outputFile);
    }

    /**
     * 压缩png格式图片方法
     * @param inputFile
     * @param outputFile
     * @throws IOException
     */
    private void compressPngImage(File inputFile, File outputFile) throws IOException {
        PngCompressor.compress(inputFile, outputFile);
    }

    /**
     * 压缩webp格式图片方法
     * @param inputFile
     * @param outputFile
     * @param quality
     * @throws IOException
     */
    public  void compressWebpImage(File inputFile, File outputFile, float quality) throws IOException {
        // 读取输入的WebP图像
        BufferedImage image = ImageIO.read(inputFile);

        // 获取WebP格式的ImageWriter
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("webp");
        if (!writers.hasNext()) {
            throw new IllegalStateException("No WebP writer found");
        }
        ImageWriter writer = writers.next();

        // 设置输出流
        try (ImageOutputStream ios = ImageIO.createImageOutputStream(outputFile)) {
            writer.setOutput(ios);

            // 设置压缩参数
            WebPWriteParam writeParam = (WebPWriteParam) writer.getDefaultWriteParam();
            writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            writeParam.setCompressionType("Lossy");
            writeParam.setCompressionQuality(quality); // 设置压缩质量,值范围 0.0 ~ 1.0
            // 写出压缩后的WebP图像
            writer.write(null, new IIOImage(image, null, null), writeParam);
        } finally {
            writer.dispose();
        }
    }

    /**
     * 获取图片类型方法
     * @param file
     * @return
     */
    private String getFileExtension(File file) {
        String name = file.getName();
        return name.substring(name.lastIndexOf('.') + 1).toLowerCase();
    }
}

3.4 apifox 调用

在这里插入图片描述

3.5 效果图

3.5.1 压缩前:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.5.2 压缩后

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

以上就是SpringBoot压缩png, jpg, jpeg, webp类型图片的实现代码的详细内容,更多关于SpringBoot压缩图片的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文