自学内容网 自学内容网

java 多线程图片压缩

使用的是 net.coobird.thumbnailator 库。

package org.example;

import net.coobird.thumbnailator.Thumbnails;

import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class App {
    private static final int THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors();
    private static final AtomicInteger filesProcessed = new AtomicInteger(0);
    private static int totalFilesToProcess = 0;

    public static void main(String[] args) {
        System.out.println("线程池大小:"+THREAD_POOL_SIZE);
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入文件夹路径(例如:d:\\ftp):");
        String folderPath = scanner.nextLine();
        File dir = new File(folderPath);

        if (!dir.exists() || !dir.isDirectory()) {
            System.out.println("文件夹路径不存在.");
            return;
        }

        totalFilesToProcess = countFiles(dir);
        long originalSize = calculateDirectorySize(dir);
        System.out.println("原始文件夹大小:: " + formatBytes(originalSize));
        System.out.println("开始压缩图片");
        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
        traverseDirectory(dir, executorService);
        executorService.shutdown();
        // 等待线程结束
        try {
            //
            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 计算压缩后的总文件大小
        long compressedSize = calculateDirectorySize(dir);
        System.out.println("压缩后文件夹总大小: " + formatBytes(compressedSize));
        double compressionRatio = (compressedSize == originalSize) ? 1.0 : (double) compressedSize / originalSize;
        System.out.println("压缩比例: " + String.format("%.2f", compressionRatio * 100) + "%");
        System.out.println("压缩图片完成");
    }

    /**
     * 遍历文件夹下所有文件,并压缩图片
     * @param dir
     * @param executorService
     */
    public static void traverseDirectory(File dir, ExecutorService executorService) {
        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                traverseDirectory(file, executorService);
            } else if (file.getName().toLowerCase().endsWith(".jpeg") ||
                    file.getName().toLowerCase().endsWith(".jpg")) {
                executorService.submit(() -> {
                    compressImage(file);
                    int processed = filesProcessed.incrementAndGet();
                    System.out.println("已处理 " + processed + " / " + totalFilesToProcess + " 文件");
                });
            }
        }
    }

    /**
     * 压缩图片
     * 逻辑:如果图片像素大于 1280,则压缩到 1280,并且质量设置为0.6,并覆盖原文件
     * @param file
     */
    public static void compressImage(File file) {
        try {
            java.awt.image.BufferedImage originalImage = Thumbnails.of(file).scale(1).asBufferedImage();
            int originalWidth = originalImage.getWidth();
            long originalSize = file.length();
            if (originalWidth > 1280) {
                double scale = (double) 1280 / originalWidth;
                Thumbnails.of(file)
                        .scale(scale)
                        .outputQuality(0.6)
                        .toFile(file);
                long compressedSize = file.length();
                System.out.println("图片 " + file.getName() + " 从 " + formatBytes(originalSize) + " 压缩到 " + formatBytes(compressedSize));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 计算文件夹大小
     * @param dir
     * @return
     */
    public static long calculateDirectorySize(File dir) {
        long totalSize = 0;
        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                totalSize += calculateDirectorySize(file);
            } else {
                totalSize += file.length();
            }
        }
        return totalSize;
    }

    /**
     * 转换文件大小为可读格式
     * @param bytes
     * @return
     */
    public static String formatBytes(long bytes) {
        String[] units = {"B", "KB", "MB", "GB", "TB"};
        int i = 0;
        while (bytes >= 1024 && i < units.length - 1) {
            bytes /= 1024;
            i++;
        }
        return String.format("%.2f %s", bytes / 1.0, units[i]);
    }

    /**
     * 计算文件夹下图片总数量
     * @param dir
     * @return
     */
    public static int countFiles(File dir) {
        int count = 0;
        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                count += countFiles(file);
            } else if (file.getName().toLowerCase().endsWith(".jpeg") ||
                    file.getName().toLowerCase().endsWith(".jpg")) {
                count++;
            }
        }
        return count;
    }
}

原文地址:https://blog.csdn.net/xingkongtianyuzhao/article/details/142354780

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!