Java压缩图片工具包thumbnailator

引入依赖

        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.21</version>
        </dependency>

创建工具类 ThumbnailatorCompressor

import net.coobird.thumbnailator.Thumbnails;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class ThumbnailatorCompressor {

    public static Dimension getImageDimensionEfficient(File imageFile) throws IOException {
        try (InputStream is = new FileInputStream(imageFile)) {
            BufferedImage image = Thumbnails.of(is)
                    .scale(1.0)
                    .asBufferedImage();
            return new Dimension(image.getWidth(), image.getHeight());
        }
    }

    /**
     * 压缩图片文件
     */
    public static void compressImage(File inputFile, File outputFile,
                                     double quality, float scale) throws IOException {
        Thumbnails.of(inputFile)
                .scale(scale)                    // 缩放比例
                .outputQuality(quality)          // 输出质量 (0.0 - 1.0)
                .outputFormat("jpg")            // 输出格式,JPEG压缩率更高
                .toFile(outputFile);
    }


    /**
     * 压缩图片文件
     */
    public static void compressImage(InputStream inputFile, OutputStream outputFile,
                                     double quality, float scale) throws IOException {
        Thumbnails.of(inputFile)
                .scale(scale)                    // 缩放比例
                .outputQuality(quality)          // 输出质量 (0.0 - 1.0)
                .outputFormat("jpg")            // 输出格式,JPEG压缩率更高
                .toOutputStream(outputFile);
    }

    /**
     * 压缩图片到指定大小
     */
    public static void compressToTargetSize(File inputFile, File outputFile,
                                            long targetSizeKB) throws IOException {
        double quality = 0.9;
        float scale = 1.0f;

        // 逐步降低质量直到达到目标大小
        for (int i = 0; i < 10; i++) {
            Thumbnails.of(inputFile)
                    .scale(scale)
                    .outputQuality(quality)
                    .outputFormat("jpg")
                    .toFile(outputFile);

            long fileSizeKB = outputFile.length() / 1024;
            if (fileSizeKB <= targetSizeKB) {
                break;
            }

            // 调整压缩参数
            quality -= 0.1;
            if (quality < 0.3) {
                scale *= 0.9f;
                quality = 0.7; // 重置质量
            }

            if (scale < 0.3) break; // 防止过度缩小
        }
    }

    /**
     * 压缩图片字节数据
     */
    public static byte[] compressImage(byte[] imageData, double quality,
                                       int maxWidth, int maxHeight) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        Thumbnails.of(new ByteArrayInputStream(imageData))
                .size(maxWidth, maxHeight)       // 最大尺寸
                .keepAspectRatio(true)           // 保持宽高比
                .outputQuality(quality)
                .outputFormat("jpg")
                .toOutputStream(outputStream);

        return outputStream.toByteArray();
    }
}

使用

    @Test
    void jpg() throws IOException {
        long startTime = System.currentTimeMillis();
        File file = new File("my.jpg");
        File newfile = new File("my_mini.jpg");
        Dimension dimension = ThumbnailatorCompressor.getImageDimensionEfficient(file);
        float scale = dimension.width > 1024 ? (float) 1024 / dimension.width: 1.0f;
        System.out.println(dimension.width + ", " + dimension.height);
        ThumbnailatorCompressor.compressImage(file, newfile, 0.2d, scale);
        System.out.println(System.currentTimeMillis() - startTime);
    }

结论

能将手机拍照的高清5M图片,压缩至200K左右,基本不损失清晰度。适用于网络app等场景。

posted @ 2025-11-08 10:43  漠孤烟  阅读(1)  评论(0)    收藏  举报