当前位置: 代码网 > it编程>编程语言>Java > 使用Java实现一个智能的图片压缩工具

使用Java实现一个智能的图片压缩工具

2025年08月07日 Java 我要评论
前言在现代web应用中,图片处理是一个常见且重要的需求。无论是用户头像、商品图片还是访客照片,都需要进行适当的处理以确保系统性能和用户体验。本文将详细介绍如何使用java实现一个智能的图片压缩工具,它

前言

在现代web应用中,图片处理是一个常见且重要的需求。无论是用户头像、商品图片还是访客照片,都需要进行适当的处理以确保系统性能和用户体验。本文将详细介绍如何使用java实现一个智能的图片压缩工具,它能够自动检测图片尺寸并进行等比例缩放。

需求分析

在实际项目中,我们经常遇到以下场景:

  • 用户上传的图片尺寸过大,需要压缩到指定大小
  • 需要保持图片的宽高比例,避免图片变形
  • 处理后的图片需要上传到云存储
  • 整个处理过程需要异常处理和日志记录

解决方案设计

整体架构

我们的解决方案包含以下几个核心组件:

  1. imageutil工具类:提供图片处理的核心功能
  2. resizevisitorimage方法:业务逻辑封装,处理完整的图片压缩流程
  3. fileclient:负责上传处理后的图片到云存储

流程图

核心代码实现

1. 图片尺寸检查

public static boolean checkimagesize(string imageurl, int size) throws exception {
    httpurlconnection connection = (httpurlconnection) new url(imageurl).openconnection();
    connection.connect();
    inputstream inputstream = connection.getinputstream();
    bufferedimage image = imageio.read(inputstream);
    ioutil.close(inputstream);
    return image.getwidth() <= size && image.getheight() <= size;
}

关键点说明:

  • 使用httpurlconnection从url获取图片
  • 通过imageio.read()读取图片到内存
  • 检查宽高是否都小于等于指定尺寸

2. 智能图片压缩

public static bufferedimage resizeimageifnecessary(string imageurl, int size) throws exception {
    // 获取原始图片
    httpurlconnection connection = (httpurlconnection) new url(imageurl).openconnection();
    connection.connect();
    inputstream inputstream = connection.getinputstream();
    bufferedimage originalimage = imageio.read(inputstream);
    ioutil.close(inputstream);

    int originalwidth = originalimage.getwidth();
    int originalheight = originalimage.getheight();

    // 如果图片尺寸超过,则进行调整
    if (originalwidth > size || originalheight > size) {
        // 计算缩放比例
        double scalex = convert.todouble(size) / originalwidth;
        double scaley = convert.todouble(size) / originalheight;
        double scale = math.min(scalex, scaley);

        // 创建缩放后的图片
        int newwidth = (int) (originalwidth * scale);
        int newheight = (int) (originalheight * scale);

        bufferedimage resizedimage = new bufferedimage(newwidth, newheight, originalimage.gettype());
        graphics2d graphics = resizedimage.creategraphics();

        // 设置高质量渲染
        graphics.setrenderinghint(renderinghints.key_interpolation, renderinghints.value_interpolation_bilinear);
        graphics.setrenderinghint(renderinghints.key_rendering, renderinghints.value_render_quality);
        graphics.setrenderinghint(renderinghints.key_antialiasing, renderinghints.value_antialias_on);

        // 执行缩放操作
        affinetransform transform = affinetransform.getscaleinstance(scale, scale);
        graphics.drawrenderedimage(originalimage, transform);

        graphics.dispose();

        return resizedimage;
    } else {
        return originalimage;
    }
}

核心算法解析:

等比例缩放计算

double scalex = convert.todouble(size) / originalwidth;
double scaley = convert.todouble(size) / originalheight;
double scale = math.min(scalex, scaley);

这段代码确保图片按比例缩放,不会变形。我们取宽度和高度缩放比例的较小值,确保图片完全在指定尺寸内。

高质量渲染设置

graphics.setrenderinghint(renderinghints.key_interpolation, renderinghints.value_interpolation_bilinear);
graphics.setrenderinghint(renderinghints.key_rendering, renderinghints.value_render_quality);
graphics.setrenderinghint(renderinghints.key_antialiasing, renderinghints.value_antialias_on);

这些设置确保缩放后的图片质量尽可能高,避免锯齿和模糊。

3. 完整的业务处理流程

private optional<string> resizevisitorimage(string originimageurl) {
    try {
        // 检查图片是否需要调整大小
        if (!imageutil.checkimagesize(originimageurl, 960)) {
            // 调整图片大小
            bufferedimage resizedimage = imageutil.resizeimageifnecessary(originimageurl, 960);

            // 将调整后的图片转换为输入流
            try (inputstream resizedinputstream = imageutil.convertbufferedimagetoinputstream(resizedimage, "jpg")) {
                // 调用 api 上传图片
                string newimageurl = fileclient.put(
                        resizedinputstream,
                        idutil.fastsimpleuuid() + ".jpg",
                        resizedinputstream.available(),
                        "visitorimage",
                        null,
                        null
                );

                return optional.of(newimageurl);
            }
        }
    } catch (exception e) {
        log.error("调整图片异常: {}", e.getmessage(), e);
    }
    return optional.empty();
}

使用示例:

// 处理图片url
string imageurl = searchdto.getimageurl();
imageurl = resizevisitorimage(imageurl).orelse(imageurl);

关键技术点

1. 资源管理

使用try-with-resources语句确保输入流正确关闭:

try (inputstream resizedinputstream = imageutil.convertbufferedimagetoinputstream(resizedimage, "jpg")) {
    // 使用流
}

2. 异常处理

整个处理过程被try-catch块包裹,确保任何异常都不会影响主流程:

catch (exception e) {
    log.error("调整图片异常: {}", e.getmessage(), e);
}

3. 函数式编程

使用optional避免空指针异常:

return optional.of(newimageurl);
// ...
return optional.empty();

性能优化建议

  • 缓存处理结果:对于相同的图片url,可以缓存处理结果,避免重复下载和处理
  • 异步处理:对于大量图片处理,可以考虑使用异步任务队列
  • 图片格式选择:根据实际需求选择合适的图片格式(jpeg、png、webp等)
  • 尺寸预检:在客户端先进行尺寸检查,减少不必要的上传

测试验证

测试用例设计

正常图片处理

  • 输入:1920x1080的图片
  • 期望输出:等比例缩放到960x540

小尺寸图片

  • 输入:800x600的图片
  • 期望输出:不处理,返回空optional

异常处理

  • 输入:无效url
  • 期望输出:记录日志,返回空optional

总结

本文介绍了一个完整的java图片处理解决方案,它具有以下特点:

  1. 智能检测:自动识别需要处理的图片
  2. 等比例缩放:保持图片原始比例,避免变形
  3. 高质量处理:使用高质量的渲染算法
  4. 异常安全:完善的异常处理机制
  5. 易于集成:简洁的api设计,易于在现有项目中集成

这个解决方案可以广泛应用于各种需要图片处理的场景,如用户头像处理、商品图片优化、内容管理系统等。

附录

工具类代码:

package cn.server.common;

import cn.hutool.core.convert.convert;
import cn.hutool.core.io.ioutil;
import cn.hutool.core.util.idutil;
import cn.hutool.core.util.strutil;
import com.google.common.base.joiner;
import org.springframework.stereotype.component;

import javax.imageio.imageio;
import java.awt.*;
import java.awt.geom.affinetransform;
import java.awt.image.bufferedimage;
import java.io.bytearrayinputstream;
import java.io.bytearrayoutputstream;
import java.io.inputstream;
import java.net.httpurlconnection;
import java.net.url;

@component
public class imageutil {


    /**
     * 校验图片大小是否超过
     *
     * @date 2025/06/19 16:54
     * @param [imageurl, size]
     * @return boolean
     */
    public static boolean checkimagesize(string imageurl, int size) throws exception {
        httpurlconnection connection = (httpurlconnection) new url(imageurl).openconnection();
        connection.connect();
        inputstream inputstream = connection.getinputstream();
        bufferedimage image = imageio.read(inputstream);
        ioutil.close(inputstream);
        return image.getwidth() <= size && image.getheight() <= size;
    }

    /**
     * 图片超过大小,压缩图片
     *
     * @date 2025/06/19 16:54
     * @param [imageurl, size]
     * @return java.awt.image.bufferedimage
     */
    public static bufferedimage resizeimageifnecessary(string imageurl, int size) throws exception {
        httpurlconnection connection = (httpurlconnection) new url(imageurl).openconnection();
        connection.connect();
        inputstream inputstream = connection.getinputstream();
        bufferedimage originalimage = imageio.read(inputstream);
        ioutil.close(inputstream);

        int originalwidth = originalimage.getwidth();
        int originalheight = originalimage.getheight();

        // 如果图片尺寸超过 ,则进行调整
        if (originalwidth > size || originalheight > size) {
            // 计算缩放比例
            double scalex = convert.todouble(size) / originalwidth;
            double scaley = convert.todouble(size) / originalheight;
            double scale = math.min(scalex, scaley);

            // 创建缩放后的图片
            int newwidth = (int) (originalwidth * scale);
            int newheight = (int) (originalheight * scale);

            bufferedimage resizedimage = new bufferedimage(newwidth, newheight, originalimage.gettype());
            graphics2d graphics = resizedimage.creategraphics();

            // 设置高质量渲染
            graphics.setrenderinghint(renderinghints.key_interpolation, renderinghints.value_interpolation_bilinear);
            graphics.setrenderinghint(renderinghints.key_rendering, renderinghints.value_render_quality);
            graphics.setrenderinghint(renderinghints.key_antialiasing, renderinghints.value_antialias_on);

            // 执行缩放操作
            affinetransform transform = affinetransform.getscaleinstance(scale, scale);
            graphics.drawrenderedimage(originalimage, transform);

            graphics.dispose();

            return resizedimage;
        } else {
            return originalimage;
        }
    }

    public static inputstream convertbufferedimagetoinputstream(bufferedimage image, string format) throws exception {
        bytearrayoutputstream outputstream = new bytearrayoutputstream();
        imageio.write(image, format, outputstream);
        outputstream.flush();
        bytearrayinputstream inputstream = new bytearrayinputstream(outputstream.tobytearray());
        outputstream.close();
        return inputstream;
    }

}

以上就是使用java实现一个智能的图片压缩工具的详细内容,更多关于java图片上传压缩的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com