本文目录导读:

我来详细介绍Java压缩本地图片的几种常用方法。
使用ImageIO(JDK自带)
基本压缩示例
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.FileOutputStream;
import java.io.IOException;
public class ImageCompressExample {
public static void compressImage(String sourcePath, String targetPath, float quality) throws IOException {
// 读取原始图片
File sourceFile = new File(sourcePath);
BufferedImage originalImage = ImageIO.read(sourceFile);
// 获取输出流
FileOutputStream fos = new FileOutputStream(targetPath);
ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
// 获取JPEG写入器
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
writer.setOutput(ios);
// 设置压缩参数
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality); // 0.0-1.0,值越小压缩越大
// 写入图像
writer.write(null, new javax.imageio.IIOImage(originalImage, null, null), param);
// 关闭资源
writer.dispose();
ios.close();
fos.close();
}
public static void main(String[] args) {
try {
compressImage("input.jpg", "output.jpg", 0.5f);
System.out.println("图片压缩完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用Thumbnails库(推荐)
添加Maven依赖
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.19</version>
</dependency>
压缩示例
import net.coobird.thumbnailator.Thumbnails;
import java.io.File;
import java.io.IOException;
public class ThumbnailsCompressExample {
/**
* 按质量压缩
*/
public static void compressByQuality(String sourcePath, String targetPath, float quality) throws IOException {
Thumbnails.of(sourcePath)
.scale(1f) // 保持原尺寸
.outputQuality(quality) // 压缩质量 0.0-1.0
.toFile(targetPath);
}
/**
* 按尺寸压缩
*/
public static void compressBySize(String sourcePath, String targetPath, int width, int height) throws IOException {
Thumbnails.of(sourcePath)
.size(width, height)
.outputQuality(0.8f)
.toFile(targetPath);
}
/**
* 按比例压缩
*/
public static void compressByScale(String sourcePath, String targetPath, double scale) throws IOException {
Thumbnails.of(sourcePath)
.scale(scale) // 0.0-1.0
.outputQuality(0.8f)
.toFile(targetPath);
}
/**
* 批量压缩
*/
public static void batchCompress(String sourceDir, String targetDir, float quality) throws IOException {
File[] files = new File(sourceDir).listFiles((dir, name) ->
name.toLowerCase().endsWith(".jpg") || name.toLowerCase().endsWith(".png")
);
if (files != null) {
for (File file : files) {
String targetPath = targetDir + File.separator + "compressed_" + file.getName();
compressByQuality(file.getAbsolutePath(), targetPath, quality);
System.out.println("压缩完成: " + file.getName());
}
}
}
public static void main(String[] args) {
try {
// 按质量压缩
compressByQuality("input.jpg", "output_quality.jpg", 0.5f);
// 按尺寸压缩
compressBySize("input.jpg", "output_size.jpg", 800, 600);
// 按比例压缩
compressByScale("input.jpg", "output_scale.jpg", 0.5);
System.out.println("压缩完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
完整压缩工具类
import javax.imageio.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Iterator;
public class ImageCompressUtil {
/**
* 图片压缩综合方法
* @param sourcePath 源文件路径
* @param targetPath 目标文件路径
* @param maxSize 最大文件大小(字节)
* @param maxWidth 最大宽度
* @param maxHeight 最大高度
*/
public static void compressImage(String sourcePath, String targetPath,
long maxSize, int maxWidth, int maxHeight) throws IOException {
File sourceFile = new File(sourcePath);
File targetFile = new File(targetPath);
// 读取原始图片
BufferedImage originalImage = ImageIO.read(sourceFile);
// 计算缩放尺寸
int width = originalImage.getWidth();
int height = originalImage.getHeight();
// 限制尺寸
if (width > maxWidth) {
height = (int) (height * (double) maxWidth / width);
width = maxWidth;
}
if (height > maxHeight) {
width = (int) (width * (double) maxHeight / height);
height = maxHeight;
}
// 缩放图片
BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = scaledImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose();
// 压缩质量调整
float quality = 0.8f;
String formatName = getFormatName(sourcePath);
// 获取写入器
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
ImageWriter writer = writers.next();
// 设置输出
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos)) {
writer.setOutput(ios);
// 设置压缩参数
ImageWriteParam param = writer.getDefaultWriteParam();
if (param.canWriteCompressed()) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
}
// 写入图像
writer.write(null, new IIOImage(scaledImage, null, null), param);
// 检查文件大小,如果太大则降低质量
byte[] imageBytes = baos.toByteArray();
while (imageBytes.length > maxSize && quality > 0.1f) {
quality -= 0.1f;
baos.reset();
try (ImageOutputStream ios2 = ImageIO.createImageOutputStream(baos)) {
writer.setOutput(ios2);
param.setCompressionQuality(quality);
writer.write(null, new IIOImage(scaledImage, null, null), param);
imageBytes = baos.toByteArray();
}
}
// 写入目标文件
try (FileOutputStream fos = new FileOutputStream(targetFile)) {
fos.write(imageBytes);
}
}
writer.dispose();
}
/**
* 获取格式名称
*/
private static String getFormatName(String fileName) {
String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
if ("jpg".equals(extension) || "jpeg".equals(extension)) {
return "jpg";
} else if ("png".equals(extension)) {
return "png";
} else if ("gif".equals(extension)) {
return "gif";
}
return "jpg";
}
/**
* 简单的质量压缩
*/
public static void simpleCompress(String sourcePath, String targetPath, float quality) throws IOException {
BufferedImage image = ImageIO.read(new File(sourcePath));
compressImageWithQuality(image, targetPath, quality);
}
private static void compressImageWithQuality(BufferedImage image, String targetPath, float quality) throws IOException {
File targetFile = new File(targetPath);
String formatName = getFormatName(targetPath);
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
ImageWriter writer = writers.next();
try (FileOutputStream fos = new FileOutputStream(targetFile);
ImageOutputStream ios = ImageIO.createImageOutputStream(fos)) {
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
if (param.canWriteCompressed()) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
}
writer.write(null, new IIOImage(image, null, null), param);
}
writer.dispose();
}
public static void main(String[] args) {
try {
// 综合压缩
compressImage("input.jpg", "output.jpg",
500 * 1024, // 最大500KB
1920, // 最大宽度
1080); // 最大高度
System.out.println("压缩完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
推荐使用方式
对于大多数场景,推荐使用 Thumbnails库,因为它:
- API简洁易用
- 支持多种压缩方式
- 性能优秀
- 内存管理好
如果不想引入第三方依赖,可以使用JDK自带的ImageIO,但需要更多的代码来确保质量和性能。
注意事项
- 质量选择:quality值0.0-1.0,一般建议0.5-0.8
- 格式选择:JPEG适合照片,PNG适合图标和文字
- 内存管理:处理大图片时注意JVM内存设置
- 异常处理:图片损坏或格式不支持时需要捕获异常
- 线程安全:ImageWriter不是线程安全的,多线程环境下需要各自创建实例
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播