开发者

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

目录
  • 1.需求
  • 2.开发中遇到的问题
  • 3. 实现代码
    • 3.1 pom 引用
    • 3.2 controller 代码
    • 3.3 Service 代码
    • 3.4 apifox 调用
    • 3.5 效果图
      • 3.5.1 压缩前:
      • 3.5.2 压缩后

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</vphpersion>
        </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.sprinjArCnUgframework.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("pnphpg".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('.')javascript + 1).toLowerCase();
    }
}

3.4 apifox 调用

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

3.5 效果图

3.5.1 压缩前:

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

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

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

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

3.5.2 压缩后

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

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

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

以上就是SpringBoot压缩png, jpg, jpeg, webp类型图片的实现代码的详细内容,更多关于SpringBoot压缩图片的资料请关注编程客栈(www.devze.com)其它相关文章!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜