最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Java實(shí)現(xiàn)一個智能的圖片壓縮工具

 更新時間:2025年08月07日 10:03:27   作者:Nicky.Ma  
在現(xiàn)代Web應(yīng)用中,圖片處理是一個常見且重要的需求,無論是用戶頭像、商品圖片還是訪客照片,都需要進(jìn)行適當(dāng)?shù)奶幚硪源_保系統(tǒng)性能和用戶體驗(yàn),本文將詳細(xì)介紹如何使用Java實(shí)現(xiàn)一個智能的圖片壓縮工具,需要的朋友可以參考下

前言

在現(xiàn)代Web應(yīng)用中,圖片處理是一個常見且重要的需求。無論是用戶頭像、商品圖片還是訪客照片,都需要進(jìn)行適當(dāng)?shù)奶幚硪源_保系統(tǒng)性能和用戶體驗(yàn)。本文將詳細(xì)介紹如何使用Java實(shí)現(xiàn)一個智能的圖片壓縮工具,它能夠自動檢測圖片尺寸并進(jìn)行等比例縮放。

需求分析

在實(shí)際項(xiàng)目中,我們經(jīng)常遇到以下場景:

  • 用戶上傳的圖片尺寸過大,需要壓縮到指定大小
  • 需要保持圖片的寬高比例,避免圖片變形
  • 處理后的圖片需要上傳到云存儲
  • 整個處理過程需要異常處理和日志記錄

解決方案設(shè)計(jì)

整體架構(gòu)

我們的解決方案包含以下幾個核心組件:

  1. ImageUtil工具類:提供圖片處理的核心功能
  2. resizeVisitorImage方法:業(yè)務(wù)邏輯封裝,處理完整的圖片壓縮流程
  3. FileClient:負(fù)責(zé)上傳處理后的圖片到云存儲

流程圖

核心代碼實(shí)現(xiàn)

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;
}

關(guān)鍵點(diǎn)說明:

  • 使用HttpURLConnection從URL獲取圖片
  • 通過ImageIO.read()讀取圖片到內(nèi)存
  • 檢查寬高是否都小于等于指定尺寸

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();

    // 如果圖片尺寸超過,則進(jìn)行調(diào)整
    if (originalWidth > size || originalHeight > size) {
        // 計(jì)算縮放比例
        double scaleX = Convert.toDouble(size) / originalWidth;
        double scaleY = Convert.toDouble(size) / originalHeight;
        double scale = Math.min(scaleX, scaleY);

        // 創(chuàng)建縮放后的圖片
        int newWidth = (int) (originalWidth * scale);
        int newHeight = (int) (originalHeight * scale);

        BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, originalImage.getType());
        Graphics2D graphics = resizedImage.createGraphics();

        // 設(shè)置高質(zhì)量渲染
        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);

        // 執(zhí)行縮放操作
        AffineTransform transform = AffineTransform.getScaleInstance(scale, scale);
        graphics.drawRenderedImage(originalImage, transform);

        graphics.dispose();

        return resizedImage;
    } else {
        return originalImage;
    }
}

核心算法解析:

等比例縮放計(jì)算

double scaleX = Convert.toDouble(size) / originalWidth;
double scaleY = Convert.toDouble(size) / originalHeight;
double scale = Math.min(scaleX, scaleY);

這段代碼確保圖片按比例縮放,不會變形。我們?nèi)挾群透叨瓤s放比例的較小值,確保圖片完全在指定尺寸內(nèi)。

高質(zhì)量渲染設(shè)置

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);

這些設(shè)置確??s放后的圖片質(zhì)量盡可能高,避免鋸齒和模糊。

3. 完整的業(yè)務(wù)處理流程

private Optional<String> resizeVisitorImage(String originImageUrl) {
    try {
        // 檢查圖片是否需要調(diào)整大小
        if (!ImageUtil.checkImageSize(originImageUrl, 960)) {
            // 調(diào)整圖片大小
            BufferedImage resizedImage = ImageUtil.resizeImageIfNecessary(originImageUrl, 960);

            // 將調(diào)整后的圖片轉(zhuǎn)換為輸入流
            try (InputStream resizedInputStream = ImageUtil.convertBufferedImageToInputStream(resizedImage, "jpg")) {
                // 調(diào)用 API 上傳圖片
                String newImageUrl = fileClient.put(
                        resizedInputStream,
                        IdUtil.fastSimpleUUID() + ".jpg",
                        resizedInputStream.available(),
                        "visitorImage",
                        null,
                        null
                );

                return Optional.of(newImageUrl);
            }
        }
    } catch (Exception e) {
        LOG.error("調(diào)整圖片異常: {}", e.getMessage(), e);
    }
    return Optional.empty();
}

使用示例:

// 處理圖片URL
String imageUrl = searchDto.getImageUrl();
imageUrl = resizeVisitorImage(imageUrl).orElse(imageUrl);

關(guān)鍵技術(shù)點(diǎn)

1. 資源管理

使用try-with-resources語句確保輸入流正確關(guān)閉:

try (InputStream resizedInputStream = ImageUtil.convertBufferedImageToInputStream(resizedImage, "jpg")) {
    // 使用流
}

2. 異常處理

整個處理過程被try-catch塊包裹,確保任何異常都不會影響主流程:

catch (Exception e) {
    LOG.error("調(diào)整圖片異常: {}", e.getMessage(), e);
}

3. 函數(shù)式編程

使用Optional避免空指針異常:

return Optional.of(newImageUrl);
// ...
return Optional.empty();

性能優(yōu)化建議

  • 緩存處理結(jié)果:對于相同的圖片URL,可以緩存處理結(jié)果,避免重復(fù)下載和處理
  • 異步處理:對于大量圖片處理,可以考慮使用異步任務(wù)隊(duì)列
  • 圖片格式選擇:根據(jù)實(shí)際需求選擇合適的圖片格式(JPEG、PNG、WebP等)
  • 尺寸預(yù)檢:在客戶端先進(jìn)行尺寸檢查,減少不必要的上傳

測試驗(yàn)證

測試用例設(shè)計(jì)

正常圖片處理

  • 輸入:1920x1080的圖片
  • 期望輸出:等比例縮放到960x540

小尺寸圖片

  • 輸入:800x600的圖片
  • 期望輸出:不處理,返回空Optional

異常處理

  • 輸入:無效URL
  • 期望輸出:記錄日志,返回空Optional

總結(jié)

本文介紹了一個完整的Java圖片處理解決方案,它具有以下特點(diǎn):

  1. 智能檢測:自動識別需要處理的圖片
  2. 等比例縮放:保持圖片原始比例,避免變形
  3. 高質(zhì)量處理:使用高質(zhì)量的渲染算法
  4. 異常安全:完善的異常處理機(jī)制
  5. 易于集成:簡潔的API設(shè)計(jì),易于在現(xiàn)有項(xiàng)目中集成

這個解決方案可以廣泛應(yīng)用于各種需要圖片處理的場景,如用戶頭像處理、商品圖片優(yōu)化、內(nèi)容管理系統(tǒng)等。

附錄

工具類代碼:

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 {


    /**
     * 校驗(yàn)圖片大小是否超過
     *
     * @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();

        // 如果圖片尺寸超過 ,則進(jìn)行調(diào)整
        if (originalWidth > size || originalHeight > size) {
            // 計(jì)算縮放比例
            double scaleX = Convert.toDouble(size) / originalWidth;
            double scaleY = Convert.toDouble(size) / originalHeight;
            double scale = Math.min(scaleX, scaleY);

            // 創(chuàng)建縮放后的圖片
            int newWidth = (int) (originalWidth * scale);
            int newHeight = (int) (originalHeight * scale);

            BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, originalImage.getType());
            Graphics2D graphics = resizedImage.createGraphics();

            // 設(shè)置高質(zhì)量渲染
            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);

            // 執(zhí)行縮放操作
            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實(shí)現(xiàn)一個智能的圖片壓縮工具的詳細(xì)內(nèi)容,更多關(guān)于Java圖片上傳壓縮的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring及Mybatis整合占位符解析失敗問題解決

    Spring及Mybatis整合占位符解析失敗問題解決

    這篇文章主要介紹了Spring及Mybatis整合占位符解析失敗問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • SpringBoot的reload加載器的方法

    SpringBoot的reload加載器的方法

    本篇文章主要介紹了SpringBoot的reload加載器的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Java 蒙特卡洛算法求圓周率近似值實(shí)例詳解

    Java 蒙特卡洛算法求圓周率近似值實(shí)例詳解

    這篇文章主要介紹了蒙特卡洛算法的起源,特點(diǎn),以及Java編程中利用蒙特卡洛算法計(jì)算圓周率近似值的實(shí)例,需要的朋友可以參考下
    2017-09-09
  • Java中this的用法實(shí)例總結(jié)

    Java中this的用法實(shí)例總結(jié)

    JAVA中的this是一個非常重要的模塊,在編程中有非常重要的地位,擅長用this的人常??梢允钩绦蚋雍啙嵑头奖?下面這篇文章主要給大家介紹了關(guān)于Java中this用法的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • Android與iOS設(shè)備MAC地址生成原理及Java實(shí)現(xiàn)詳解

    Android與iOS設(shè)備MAC地址生成原理及Java實(shí)現(xiàn)詳解

    在無線網(wǎng)絡(luò)通信中,MAC(Media Access Control)地址是設(shè)備的唯一網(wǎng)絡(luò)標(biāo)識符,本文主要介紹了Android與iOS設(shè)備MAC地址生成原理以及Java實(shí)現(xiàn)方法,需要的可以了解下
    2025-05-05
  • Java內(nèi)部類之間的閉包和回調(diào)詳解

    Java內(nèi)部類之間的閉包和回調(diào)詳解

    相信閉包和回調(diào)對每位學(xué)習(xí)Java的人來說都不陌生,那么今天小編和大家分享一篇關(guān)于Java內(nèi)部類之間的閉包和回調(diào),有需要的可以參考借鑒。
    2016-09-09
  • SpringBoot 工程中的異常處理方式

    SpringBoot 工程中的異常處理方式

    這篇文章主要介紹了SpringBoot 工程中的異常處理方式,幫助大家更好的理解和學(xué)習(xí)使用springboot框架,感興趣的朋友可以了解下
    2021-02-02
  • SpringBoot如何引入緩存提高單次查詢數(shù)據(jù)效率

    SpringBoot如何引入緩存提高單次查詢數(shù)據(jù)效率

    這篇文章主要介紹了SpringBoot如何引入緩存提高單次查詢數(shù)據(jù)效率問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 基于Scala和Java方法的相互調(diào)用

    基于Scala和Java方法的相互調(diào)用

    這篇文章主要介紹了Scala和Java方法的相互調(diào)用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java字節(jié)流FileInputStream和FileOutputStream從入門到實(shí)踐

    Java字節(jié)流FileInputStream和FileOutputStream從入門到實(shí)踐

    FileOutputStream 是與 FileInputStream 相對應(yīng)的文件輸出流類,用來實(shí)現(xiàn)向文件中寫入數(shù)據(jù),寫入數(shù)據(jù)的基本單位是字節(jié),這篇文章主要介紹了Java字節(jié)流FileInputStream和FileOutputStream從入門到實(shí)踐的相關(guān)資料,需要的朋友可以參考下
    2026-06-06

最新評論

乌拉特后旗| 平邑县| 呈贡县| 巴青县| 平阴县| 元朗区| 黄龙县| 湾仔区| 安远县| 龙海市| 乐山市| 方正县| 旅游| 佛冈县| 剑阁县| 乌鲁木齐市| 年辖:市辖区| 景泰县| 于田县| 平远县| 宁阳县| 吴忠市| 江都市| 汕尾市| 满城县| 定陶县| 荆州市| 武胜县| 石景山区| 北流市| 祁阳县| 吉木乃县| 定襄县| 汉阴县| 百色市| 开江县| 利川市| 山东| 凌云县| 化隆| 星子县|