vue+java实现图片批量压缩

最近做了一个功能批量图片压缩,在不对接第三方api的条件下应该怎么做

先看看效果:https://office.zjdiante.com/imageTool/compress

1.安装 ImageMagick,我用的版本是7

2.后端代码工具类

java 复制代码
package com.ruoyi.basicTool.imageTool.utils;

import cn.hutool.core.io.IoUtil;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

/**
 * 调用本机 ImageMagick 7 命令行(默认可执行文件名为 {@code magick})。
 * <p>解析顺序:系统属性 {@code imagemagick.binary}(可由 {@code application.yml} 中 {@code imagemagick.binary} 在启动时注入)
 * → 环境变量 {@code IMAGEMAGICK_BINARY} → Windows 下默认 {@code magick.exe} → 其他系统默认 {@code magick}。</p>
 * <p>Windows 若未将安装目录加入 PATH,请将 {@code imagemagick.binary} 设为 {@code magick.exe} 的绝对路径,例如
 * {@code C:/Program Files/ImageMagick-7.1.1-Q16-HDRI/magick.exe}。</p>
 */
public final class ImageMagickRunUtils {

    private static final int MAGICK_TIMEOUT_SECONDS = 120;

    private ImageMagickRunUtils() {
    }

    public static String magickBinary() {
        String p = System.getProperty("imagemagick.binary");
        if (StringUtils.isNotEmpty(p)) {
            return p.trim();
        }
        String env = System.getenv("IMAGEMAGICK_BINARY");
        if (StringUtils.isNotEmpty(env)) {
            return env.trim();
        }
        if (System.getProperty("os.name", "").toLowerCase(Locale.ROOT).contains("windows")) {
            return "magick.exe";
        }
        return "magick";
    }

    public static void runMagick(Path expectedOut, List<String> cmd) throws Exception {
        ProcessBuilder pb = new ProcessBuilder(cmd);
        pb.redirectErrorStream(true);
        Process proc;
        try {
            proc = pb.start();
        } catch (IOException e) {
            if (e.getMessage() != null && (e.getMessage().contains("error=2") || e.getMessage().contains("Cannot run program"))) {
                throw new IOException(
                        "无法启动 ImageMagick(进程找不到可执行文件)。CMD 能运行 magick 不代表 JVM 的 PATH 相同;"
                                + "请在 CMD 执行 where magick 得到 magick.exe 绝对路径,写入 application.yml 的 imagemagick.binary,"
                                + "或设置环境变量 IMAGEMAGICK_BINARY。",
                        e);
            }
            throw e;
        }
        String output;
        try (InputStream es = proc.getInputStream()) {
            if (!proc.waitFor(MAGICK_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
                proc.destroyForcibly();
                throw new IOException("ImageMagick 执行超时");
            }
            output = IoUtil.readUtf8(es);
        }
        if (proc.exitValue() != 0) {
            throw new IOException("ImageMagick 失败: " + truncate(output, 800));
        }
        if (!Files.exists(expectedOut) || Files.size(expectedOut) == 0) {
            throw new IOException("ImageMagick 未生成有效输出: " + truncate(output, 800));
        }
    }

    private static String truncate(String s, int max) {
        if (s == null) {
            return "";
        }
        String t = s.replace("\r", " ").replace("\n", " ").trim();
        return t.length() <= max ? t : t.substring(0, max) + "...";
    }
}

有想要做类似不明白的小伙伴,可以点开:https://office.zjdiante.com/ 联系我

相关推荐
老白干2 分钟前
基于 Spring AOP 的操作日志记录:以 DeptController 增删接口为例
java·python·spring
MartinYeung521 分钟前
npm爆发大规模供应链攻击 蠕虫污染 2000+ 个包版本: 深度技术剖析
前端·npm·node.js
huabuyu22 分钟前
治好 AI 长回答的卡、闪、膨胀:渲染开销从 50 万次砍到 1000
前端·javascript
嘟嘟071725 分钟前
学了 useContext 还是不理解?从 prop drilling 到 useMouse 的一次完整复盘
前端·javascript·react.js
玉宇夕落26 分钟前
React useContext 与自定义 Hook —— 从零到一理解跨组件通信与状态共享
前端
涛涛ing27 分钟前
一行命令让AI帮你修性能问题:perfpatch正在改变前端优化的游戏规则
前端
huabuyu29 分钟前
模型吐到一半的 JSON 为什么不崩、不卡、不抖?流式 Function Call 的三层修复
前端·javascript
触底反弹32 分钟前
JS 运行原理与 Event Loop:从 Web Worker 实战说起
前端·javascript·react.js
无糖可可果33 分钟前
React Context 与自定义 Hooks 学习分享
前端
胡萝卜术36 分钟前
声明式与命令式的边界:从鉴权路由守卫到 useRef 的引用哲学
前端·javascript·面试