当前位置: 首页 > article >正文

运行在docker环境下的图片压缩小工具

声明

1. 本工具主要针对png、jpg、jpeg格式图片进行压缩,由于png图片的特殊性,压缩过程中会将png转换成jpg再压缩
2. 考虑到jdk环境的问题,所以本工具需要运行在docker容器中,使用时你需要有个docker环境
3. 若符合你的需求,请继续看下面使用步骤


1. 新建maven项目,pom文件中加入

<dependencies>
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>image-compression</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.test.img.ImageCompression</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

说明:项目依赖了thumbnailatorcommons-io,若获取jar包失败,可尝试将jar下载本地,然后打入本地仓库

2.源码

package com.test.img;

import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import java.util.Scanner;

public class ImageCompression {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入图片源路径:");
        String inputDirPath = scanner.nextLine();

        if (inputDirPath == null || inputDirPath.isEmpty() || inputDirPath.trim().isEmpty()) {
            System.out.println("输入路径不能为空,请重新输入!");
            return;
        }

        System.out.println("请输入图片输出路径:");
        String outputDirPath = scanner.nextLine();

        if (outputDirPath == null || outputDirPath.isEmpty() || outputDirPath.trim().isEmpty()) {
            System.out.println("输入路径不能为空,请重新输入!");
            return;
        }

        compressImages(inputDirPath, outputDirPath);
    }

    public static void compressImages(String inputDirPath, String outputDirPath) {
        Path inputDir = Paths.get(inputDirPath);
        Path outputDir = Paths.get(outputDirPath);

        try {
            // 创建输出目录
            Files.createDirectories(outputDir);

            // 获取输入目录下的所有文件
            Collection<File> files = FileUtils.listFiles(new File(inputDir.toString()), null, true);

            ExecutorService executor = Executors.newFixedThreadPool(6); // 根据需要调整线程数

            for (File file : files) {
                if (file.isFile() && isImageFile(file.getName()) && isValidFileName(file.getName())) {
                    String relativePath = inputDir.relativize(file.toPath()).toString();
                    String outputPath = outputDir.resolve(relativePath).toString();

                    // 创建输出目录结构
                    Files.createDirectories(Paths.get(outputPath).getParent());

                    // 提交任务到线程池
                    executor.submit(() -> {
                        try {
                            Thumbnails.Builder<File> builder = Thumbnails.of(file)
                                    .scale(1f)
                                    .outputQuality(getQuality(file.length()));

                            String extension = FilenameUtils.getExtension(file.getName());
                            if ("png".equals(extension)) {
                                builder.outputFormat("jpg");
                            }

                            builder.toFile(outputPath);
                        } catch (Exception e) {
                            System.err.println("发生错误:" + e.getMessage());
                            e.printStackTrace();
                        }
                    });
                }
            }

            // 关闭线程池
            executor.shutdown();
            executor.awaitTermination(1, TimeUnit.HOURS);

            System.out.println("图片压缩完成!");
        } catch (IOException | InterruptedException e) {
            System.err.println("发生错误:" + e.getMessage());
            e.printStackTrace();
        }
    }

    // 排除掉名称以blob_开头的文件
    private static boolean isValidFileName(String fileName) {
        return !fileName.startsWith("blob_");
    }

    private static boolean isImageFile(String fileName) {
        String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        return extension.equals("jpg") || extension.equals("jpeg") || extension.equals("png") || extension.equals("gif");
    }

    private static double getQuality(long size) {
        if (size < 900) {
            return 0.85;
        } else if (size < 2047) {
            return 0.6;
        } else if (size < 3275) {
            return 0.44;
        }
        return 0.3;
    }
}

说明:使用时根据实际需要调整源码

3.将项目打成jar包

mvn clean package

4.Dockerfile

# 使用java8镜像作为基础镜像
FROM java:8

RUN mkdir /test

# 设置工作目录
WORKDIR /test

ADD /image-compression.jar .

VOLUME /test

# 设置容器启动命令,这里传递命令行参数
CMD ["java", "-jar", "image-compression.jar", "param1", "param2"]

5.新建copy.bat

@echo off
setlocal

:: Step 1: Determine the path to the generated JAR file
set JAR_FILE=target\image-compression.jar
if not exist %JAR_FILE% (
    echo Error: JAR file not found.
    exit /b 1
)

:: Step 2: Create the dest directory if it doesn't exist
echo Creating dest directory...
mkdir dest 2>nul

:: Step 3: Copy the JAR file to the dest directory
echo Copying the JAR file to dest directory...
xcopy /F /I /Y "%JAR_FILE%" "dest\"

:: Step 4: Copy the Dockerfile to the dest directory
echo Copying the Dockerfile to dest directory...
xcopy /F /I /Y "Dockerfile" "dest\"

echo Done!
endlocal

6.执行copy.bat

完成后

在这里插入图片描述

7.将生成的dest目录上传至目标服务器,进入dest目录,构建镜像

cd /dest
docker build -t image-compression:v1 .

8.运行容器

docker run -it --rm -v /test/upload/2023/:/2023 -v /test/upload/2023bak/:/2023bak -v /test/upload/2024/:/2024 -v /test/upload/2024bak/:/2024bak --name image-compression image-compression:v1

说明:运行容器时需要执行目录,防止在容器内部找不到目录,程序报错

  • -v 就是为了指定目录挂载,这里将宿主机器的/test/upload/2023映射到容器内的/2023,其它路径挂在同理
  • -it使容器采用交互式运行,--rm会在容器退出后自动删除容器

9.分别输入图片源路径、图片输出路径,将进行压缩,压缩完成后容器自动删除


http://www.kler.cn/a/316028.html

相关文章:

  • MaxKB
  • 通过MongoDB Atlas 实现语义搜索与 RAG——迈向AI的搜索机制
  • AndroidStudio-常用布局
  • web实操5——http数据详解,request对象功能
  • u盘加密软件有哪些?2025年必备的u盘加密神器分享(共6款!提前布局!)
  • 【AutoGen 】简介
  • Qt集成Direct2D绘制,实现离屏渲染
  • OpenHarmony(鸿蒙南向开发)——轻量系统内核(LiteOS-M)【SHELL】
  • ARM中的寄存器
  • Zabbix 6.4添加中文语言
  • IT 人转架构设计必备:项目学习资料+视频分享,涵盖运维管理全内容
  • C++ 构造函数最佳实践
  • Jmeter压力测试-ServerAgent-2.2.3闪退问题解决
  • 【编程基础知识】MySQL中什么叫做聚簇索引、非聚簇索引、回表、覆盖索引
  • Spring Boot文件上传
  • Spring Boot 入门面试五道题
  • 【图灵完备 Turing Complete】游戏经验攻略分享 Part.6 处理器架构2 函数
  • 从局部到全局:深入理解Java Web的作用域机制
  • 【SpinalHDL】Scala/SpinalHDL联合编程之实例化
  • Spring Boot管理用户数据
  • 九、按照官网的操作:安装artifactory+mariadb--失败了
  • AI资深导师指导-ChatGPT深度科研工作应用、论文撰写、数据分析及机器学习与AI绘图
  • MySQL|MySQL 中 `DATE_FORMAT()` 函数的使用
  • 如何进行Ubuntu磁盘空间深度清理?
  • MySQL数据库迁移与备份实录
  • 【RabbitMQ】应用问题