1. 概述

在这个教程中,我们将探讨如何使用Java来压缩图像。我们将首先利用Java内置库进行图像压缩,然后介绍Apache Commons Imaging库作为备选方案。让我们从了解图像压缩的基本概念开始。

2. 图像压缩是什么?

图像压缩允许我们减小图像文件的大小,同时在视觉质量上不产生显著损失。压缩方法主要有两种:有损压缩通过接受较低的图像质量换取更小的文件尺寸,如JPEG和WebP格式无损压缩则在压缩过程中保留数据和信息,如PNG和GIF格式

我们将重点讲解使用最广泛的有损压缩格式JPEG进行图像压缩,随后还会介绍如何优化PNG图像(PNG图像优化)。

3. 使用Java Image I/O库压缩图像

首先,我们将使用Java的内置Image I/OAPI来读取和写入图像,它支持多种格式,包括JPEG、PNG、BMP和GIF。以下是使用Java Image I/O进行图像压缩的步骤:

File inputFile = new File("input_image.jpg");

BufferedImage inputImage = ImageIO.read(inputFile);

Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = writers.next();

File outputFile = new File("output.jpg");
ImageOutputStream outputStream = ImageIO.createImageOutputStream(outputFile);
writer.setOutput(outputStream);

ImageWriteParam params = writer.getDefaultWriteParam();
params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
params.setCompressionQuality(0.5f);

writer.write(null, new IIOImage(inputImage, null, null), params);

outputStream.close();
writer.dispose();

首先,从资源文件读取图像,然后创建一个针对JPEG格式的ImageWriter,设置输出文件。在写入图像前,我们需要创建ImageWriteParam对象来定义压缩模式和质量,这里设定为50%。最后,写入图像、关闭输出流并清理写入器。

例如,将一个示例图像压缩50%,文件大小从790KB减小到656KB,约为原始大小的83%。图片质量的变化并不明显:

4. 使用Thumbnailer库压缩图像

Thumbnails库是一个简单且功能丰富的库,用于调整和压缩图像。首先在pom.xml中添加该库:

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

接下来,使用Thumbnails类进行图像压缩:

File input = new File("input_image.jpg");
File output = new File("output.jpg");

Thumbnails.of(input)
  .scale(1) 
  .outputQuality(0.5)
  .toFile(output);

这里,scale(1)方法保持原始图像尺寸,而outputQuality(0.5)设置输出质量为50%。

5. 使用Pngtastic库压缩PNG图像

PNG优化是专为PNG图像设计的压缩类型。我们将使用Pngtastic库对PNG图像进行优化。首先,在pom.xml中添加最新库依赖:

<dependency>
    <groupId>com.github.depsypher</groupId>
    <artifactId>pngtastic</artifactId>
    <version>1.7</version>
</dependency>

最后,我们可以使用PngOptimizer类压缩PNG文件:

PngImage inputImage = new PngImage(Files.newInputStream(Paths.get(inputPath)));

PngOptimizer optimizer = new PngOptimizer();
PngImage optimized = optimizer.optimize(inputImage);

OutputStream output = Files.newOutputStream(Paths.get(outputPath));
optimized.writeDataOutputStream(output);

使用.optimize()方法让库自动决定最佳压缩方式。由于是无损压缩,很难显著减小文件大小。在这里,我们把大小从500 KB减小到481 KB。

6. 总结

本文介绍了使用Java进行图像压缩的两种方法:内置的Java Image I/O API和Apache Commons Imaging库。此外,我们还演示了如何使用Pngtastic库进行PNG图像的无损压缩。完整的示例代码可以在GitHub上找到:GitHub链接