杰瑞科技汇

Java如何压缩图片至指定大小?

Java 图片压缩到指定大小

在Java中,你可以使用多种方法将图片压缩到指定的大小(以KB或MB为单位),以下是几种常用的实现方法:

方法1:使用BufferedImage和ImageIO

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageCompressor {
    public static void compressImage(File inputFile, File outputFile, long targetSizeKB) throws IOException {
        // 读取原始图片
        BufferedImage originalImage = ImageIO.read(inputFile);
        // 计算原始图片大小
        long originalSizeKB = inputFile.length() / 1024;
        // 如果原始图片已经小于目标大小,直接复制
        if (originalSizeKB <= targetSizeKB) {
            Files.copy(inputFile.toPath(), outputFile.toPath());
            return;
        }
        // 计算压缩质量(0.0-1.0)
        double quality = calculateQuality(originalSizeKB, targetSizeKB);
        // 使用ImageIO写入压缩后的图片
        // 注意:这里需要根据图片格式选择合适的写入器
        ImageIO.write(originalImage, "jpg", outputFile);
        // 如果压缩后仍然太大,递归调用
        if (outputFile.length() / 1024 > targetSizeKB) {
            compressImage(inputFile, outputFile, targetSizeKB);
        }
    }
    private static double calculateQuality(long originalSizeKB, long targetSizeKB) {
        // 简单线性计算,可以根据需要调整算法
        return (double) targetSizeKB / originalSizeKB;
    }
    public static void main(String[] args) {
        try {
            File inputFile = new File("input.jpg");
            File outputFile = new File("output.jpg");
            long targetSizeKB = 100; // 目标大小100KB
            compressImage(inputFile, outputFile, targetSizeKB);
            System.out.println("图片压缩完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

方法2:使用Thumbnailator库(推荐)

Thumbnailator是一个简单易用的Java图片缩略图库,支持高质量压缩:

import net.coobird.thumbnailator.Thumbnails;
import java.io.File;
import java.io.IOException;
public class ThumbnailatorCompressor {
    public static void compressImage(File inputFile, File outputFile, long targetSizeKB) throws IOException {
        // 读取原始图片大小
        long originalSizeKB = inputFile.length() / 1024;
        // 如果原始图片已经小于目标大小,直接复制
        if (originalSizeKB <= targetSizeKB) {
            Files.copy(inputFile.toPath(), outputFile.toPath());
            return;
        }
        // 计算压缩质量
        double quality = calculateQuality(originalSizeKB, targetSizeKB);
        // 使用Thumbnailator压缩图片
        Thumbnails.of(inputFile)
                .scale(1.0) // 保持原始尺寸
                .outputQuality(quality)
                .toFile(outputFile);
        // 如果压缩后仍然太大,递归调用
        if (outputFile.length() / 1024 > targetSizeKB) {
            compressImage(inputFile, outputFile, targetSizeKB);
        }
    }
    private static double calculateQuality(long originalSizeKB, long targetSizeKB) {
        // 简单线性计算,可以根据需要调整算法
        return (double) targetSizeKB / originalSizeKB;
    }
    public static void main(String[] args) {
        try {
            File inputFile = new File("input.jpg");
            File outputFile = new File("output.jpg");
            long targetSizeKB = 100; // 目标大小100KB
            compressImage(inputFile, outputFile, targetSizeKB);
            System.out.println("图片压缩完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

方法3:使用Java Advanced Imaging (JAI)

对于更高级的图片处理需求,可以使用JAI:

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.media.jai.TileCache;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class JaiCompressor {
    public static void compressImage(File inputFile, File outputFile, long targetSizeKB) throws IOException {
        // 读取原始图片
        RenderedOp image = JAI.create("fileload", inputFile.getPath());
        // 计算原始图片大小
        long originalSizeKB = inputFile.length() / 1024;
        // 如果原始图片已经小于目标大小,直接复制
        if (originalSizeKB <= targetSizeKB) {
            Files.copy(inputFile.toPath(), outputFile.toPath());
            return;
        }
        // 计算压缩质量
        float quality = (float) calculateQuality(originalSizeKB, targetSizeKB);
        // 使用JAI压缩图片
        RenderedOp compressedImage = JAI.create("encode", image, outputFile.getPath(), "JPEG", quality);
        // 如果压缩后仍然太大,递归调用
        if (outputFile.length() / 1024 > targetSizeKB) {
            compressImage(inputFile, outputFile, targetSizeKB);
        }
    }
    private static double calculateQuality(long originalSizeKB, long targetSizeKB) {
        // 简单线性计算,可以根据需要调整算法
        return (double) targetSizeKB / originalSizeKB;
    }
    public static void main(String[] args) {
        try {
            File inputFile = new File("input.jpg");
            File outputFile = new File("output.jpg");
            long targetSizeKB = 100; // 目标大小100KB
            compressImage(inputFile, outputFile, targetSizeKB);
            System.out.println("图片压缩完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

注意事项

  1. 图片格式:不同的图片格式(JPEG、PNG、WebP等)有不同的压缩特性,JPEG通常更适合有损压缩。
  2. 质量计算:上述示例使用简单的线性计算,实际应用中可能需要更复杂的算法来达到最佳效果。
  3. 递归压缩:示例中使用了递归来确保最终文件大小符合要求,但要注意避免无限递归。
  4. 性能考虑:对于大图片或批量处理,考虑使用多线程或异步处理。
  5. 依赖:Thumbnailator需要额外添加依赖,Maven坐标:
    <dependency>
        <groupId>net.coobird</groupId>
        <artifactId>thumbnailator</artifactId>
        <version>0.4.20</version>
    </dependency>

方法可以根据你的具体需求进行调整和优化。

分享:
扫描分享到社交APP
上一篇
下一篇