Java 图片压缩优化:提升效率、减小体积、优化代码
Java 图片压缩优化:提升效率、减小体积、优化代码
以下代码是一个简单的 Java 图片压缩程序,可以将图片压缩到指定大小,并提供了一些优化建议:
package com.iyunan.utils;
import java.io.File;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.file.Files;
import javax.imageio.ImageIO;
public class CompressPictureUtils {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
CompressPictureUtils.compress('E:\gallery/orign_pic71703.JPG', 'E:\gallery\110.jpg');
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println('程序执行时间为:' + elapsedTime + ' 毫秒');
}
/**
* 图片压缩最大宽1920像素
*/
public static final Integer PICTURE_COMPRESS_WIDTH_MAX = 1920; // 1920像素
/**
* 图片压缩最大高1920像素
*/
public static final Integer PICTURE_COMPRESS_HEIGHT_MAX = 1920; // 1920像素
/**
* 图片压缩最小容量64KB
*/
public static final Integer PICTURE_COMPRESS_MIN = 1 << 16; // 64KB
/**
* 图片压缩最大容量64MB
*/
public static final Integer PICTURE_COMPRESS_MAX = 1 << 26; // 64MB
/**
* 图片压缩最小容量差64KB
*/
public static final Integer PICTURE_COMPRESS_DIFFER_MIN = 1 << 16; // 64KB
public static void compress(String sourceImagePath, String destinationImagePath) {
CoputUtils.getFreeMemoryPercentage();
try {
/* 过滤小于64kb和大于64mb的图片 */
File sourceImageFile = new File(sourceImagePath);
File destinationImageFile = new File(destinationImagePath);
long sourceImageSize = sourceImageFile.length();
if (sourceImageSize == 0) {
throw new Exception('empty');
}
if (sourceImageSize < PICTURE_COMPRESS_MIN) {
throw new Exception('small');
}
if (sourceImageSize > PICTURE_COMPRESS_MAX) {
throw new Exception('large');
}
/* 设置图片大小 */
BufferedImage inputImage = ImageIO.read(sourceImageFile);
int sourceImageWidth = inputImage.getWidth();
int sourceImageHeight = inputImage.getHeight();
int destinationImageWidth = sourceImageWidth;
int destinationImageHeight = sourceImageHeight;
if (sourceImageWidth > PICTURE_COMPRESS_WIDTH_MAX || sourceImageHeight > PICTURE_COMPRESS_HEIGHT_MAX) {
if (sourceImageWidth > sourceImageHeight) {
destinationImageWidth = PICTURE_COMPRESS_WIDTH_MAX;
destinationImageHeight = destinationImageWidth * sourceImageHeight / sourceImageWidth;
} else {
destinationImageHeight = PICTURE_COMPRESS_HEIGHT_MAX;
destinationImageWidth = destinationImageHeight * sourceImageWidth / sourceImageHeight;
}
}
/* 压缩图片 */
Image image = inputImage.getScaledInstance(destinationImageWidth, destinationImageHeight, Image.SCALE_DEFAULT);
BufferedImage outputImage = new BufferedImage(destinationImageWidth, destinationImageHeight, BufferedImage.TYPE_INT_RGB);
Graphics graphics = outputImage.getGraphics();
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
ImageIO.write(outputImage, 'jpg', destinationImageFile);
/* 过滤比原图小8kb以下的的图片 */
long destinationImageSize = destinationImageFile.length();
if (destinationImageSize > (sourceImageSize - PICTURE_COMPRESS_DIFFER_MIN)) {
throw new Exception('low');
}
CoputUtils.getFreeMemoryPercentage();
} catch (Exception e) {
try {
String msg = e.getMessage();
if (msg == 'small' || msg == 'low') { // 过小或压缩率过低,保存原图
File sourceImageFile = new File(sourceImagePath);
File destinationImageFile = new File(destinationImagePath);
destinationImageFile.delete();
Files.copy(sourceImageFile.toPath(), destinationImageFile.toPath());
} else { // 空或过大或异常,保存空图
File emptyfile = new File(destinationImagePath);
emptyfile.delete();
emptyfile.createNewFile();
}
} catch (Exception e1) {}
}
}
}
优化建议
-
使用多线程进行批量压缩,提高效率: 可以使用
ExecutorService创建线程池,并使用Future管理每个压缩任务的结果。 -
使用图片压缩库,如 TinyPNG,进行压缩,可以得到更小的图片大小: 可以使用 TinyPNG 的 API 或库来进行图片压缩,可以获得更高的压缩率。
-
压缩图片时,可以选择更合适的压缩算法,如 JPEG、PNG 等,以得到更小的文件大小: JPEG 适合于照片等色彩丰富的图片,PNG 适合于线条图等色彩简单的图片。
-
优化代码结构,封装重复代码,提高代码复用性和可维护性: 可以将图片压缩逻辑封装成一个独立的类或方法,并提供一些配置参数,例如压缩算法、压缩质量等。
-
使用 try-with-resources 语句,自动关闭资源,防止资源泄漏: 在使用
InputStream、OutputStream等资源时,可以使用try-with-resources语句来自动关闭资源。 -
使用日志记录程序执行过程和异常信息,方便问题排查和优化: 可以使用
java.util.logging或log4j等日志框架来记录程序的执行过程和异常信息。
通过以上优化措施,可以显著提升图片压缩效率,减小图片体积,提高代码质量。
注意: 上述代码示例仅供参考,实际应用中需要根据具体需求进行修改和完善。
原文地址: https://www.cveoy.top/t/topic/jw9X 著作权归作者所有。请勿转载和采集!