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) {}
        }
    }
}

优化建议

  1. 使用多线程进行批量压缩,提高效率: 可以使用 ExecutorService 创建线程池,并使用 Future 管理每个压缩任务的结果。

  2. 使用图片压缩库,如 TinyPNG,进行压缩,可以得到更小的图片大小: 可以使用 TinyPNG 的 API 或库来进行图片压缩,可以获得更高的压缩率。

  3. 压缩图片时,可以选择更合适的压缩算法,如 JPEG、PNG 等,以得到更小的文件大小: JPEG 适合于照片等色彩丰富的图片,PNG 适合于线条图等色彩简单的图片。

  4. 优化代码结构,封装重复代码,提高代码复用性和可维护性: 可以将图片压缩逻辑封装成一个独立的类或方法,并提供一些配置参数,例如压缩算法、压缩质量等。

  5. 使用 try-with-resources 语句,自动关闭资源,防止资源泄漏: 在使用 InputStreamOutputStream 等资源时,可以使用 try-with-resources 语句来自动关闭资源。

  6. 使用日志记录程序执行过程和异常信息,方便问题排查和优化: 可以使用 java.util.logginglog4j 等日志框架来记录程序的执行过程和异常信息。

通过以上优化措施,可以显著提升图片压缩效率,减小图片体积,提高代码质量。

注意: 上述代码示例仅供参考,实际应用中需要根据具体需求进行修改和完善。

Java 图片压缩优化:提升效率、减小体积、优化代码

原文地址: https://www.cveoy.top/t/topic/jw9X 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录