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();
}
}
}
注意事项
- 图片格式:不同的图片格式(JPEG、PNG、WebP等)有不同的压缩特性,JPEG通常更适合有损压缩。
- 质量计算:上述示例使用简单的线性计算,实际应用中可能需要更复杂的算法来达到最佳效果。
- 递归压缩:示例中使用了递归来确保最终文件大小符合要求,但要注意避免无限递归。
- 性能考虑:对于大图片或批量处理,考虑使用多线程或异步处理。
- 依赖:Thumbnailator需要额外添加依赖,Maven坐标:
<dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</artifactId> <version>0.4.20</version> </dependency>
方法可以根据你的具体需求进行调整和优化。
