首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 圖片處理實戰:縮略圖生成與座標裁剪完整指南

     編輯:Java 相關知識

在相簿瀏覽、頭像上傳等場景中,縮略圖生成與區域裁剪是高頻需求。本文提供兩個生產級工具類:ImageUtil(等比/強制縮略圖)與 ImageUtil2(座標裁剪),並詳細說明前端座標獲取與尺寸適配技巧。

一、縮略圖生成:ImageUtil.thumbnailImage()

核心功能

  • 支援主流格式:BMP、JPG、PNG、GIF、WBMP 等
  • 兩種模式:等比縮放(預設,保持長寬比)與強制尺寸(可能變形)
  • 自動輸出至原目錄,檔名前綴預設 thumb_
  • 完善的日誌記錄與異常處理

關鍵實作邏輯

public void thumbnailImage(String imagePath, int w, int h, 
                           String prefix, boolean force) {
    File imgFile = new File(imagePath);
    if (!imgFile.exists()) { log.warn("圖片不存在"); return; }

    // 校驗副檔名
    String suffix = getSuffix(imgFile);
    if (!isValidSuffix(suffix)) { log.error("非支援格式"); return; }

    Image srcImg = ImageIO.read(imgFile);
    int srcW = srcImg.getWidth(null), srcH = srcImg.getHeight(null);

    // 等比模式:計算最佳尺寸
    if (!force) {
        double ratioW = (double) srcW / w;
        double ratioH = (double) srcH / h;
        if (ratioW < ratioH) { // 以寬為基準
            if (srcW > w) h = (int) Math.round(srcH * w / (double) srcW);
        } else { // 以高為基準
            if (srcH > h) w = (int) Math.round(srcW * h / (double) srcH);
        }
    }

    // 繪製縮略圖
    BufferedImage thumb = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    Graphics g = thumb.getGraphics();
    g.drawImage(srcImg, 0, 0, w, h, Color.LIGHT_GRAY, null);
    g.dispose();

    // 輸出
    String outPath = imgFile.getParent() + File.separator + prefix + imgFile.getName();
    ImageIO.write(thumb, suffix, new File(outPath));
    log.debug("縮略圖生成成功:{}", outPath);
}

使用範例

// 等比縮略圖,長邊不超過 150px
new ImageUtil().thumbnailImage("C:/photos/avatar.jpg", 100, 150, "thumb_", false);

二、座標裁剪:ImageUtil2.cutImage()

適用場景

使用者在前端(如 Jcrop、自製 JS 拖拉框)選取裁剪區域,獲得 x, y, width, height 四個參數,後端據此從原圖切出對應區域。

核心實作(基於 ImageReader 區域讀取,記憶體效率高)

public void cutImage(File srcImg, OutputStream output, Rectangle rect) {
    // 校驗檔案與格式(同上)
    FileInputStream fis = new FileInputStream(srcImg);
    ImageInputStream iis = ImageIO.createImageInputStream(fis);
    ImageReader reader = ImageIO.getImageReadersBySuffix(suffix).next();
    reader.setInput(iis, true);

    ImageReadParam param = reader.getDefaultReadParam();
    param.setSourceRegion(rect); // 關鍵:設定讀取區域
    BufferedImage bi = reader.read(0, param);
    ImageIO.write(bi, suffix, output);
    
    // 關閉資源...
}

多載方法便利呼叫


// 直接指定輸出資料夾,自動加前綴 cut_
cutImage(srcImgFile, destFolder, new Rectangle(x, y, w, h));

// 字串路徑版
cutImage("src.jpg", "destFolder", 40, 28, 224, 228);

三、前端座標獲取與尺寸適配實戰指南

1. 自製 JS 裁剪元件(參考慕課網範例)

左側拖拉選區,右側即時預覽。透過 F12 觀察 DOM 變化,確認 x, y, width, height 對應屬性:

JS 裁剪元件示意圖

圖:左側可拖拉選區,右側即時預覽

2. Jcrop 插件替代方案

Jcrop 參數示意圖

Jcrop 直接暴露 x, y, w, h 參數,整合極簡單。但缺點是前端顯示區域固定,大圖會被壓縮顯示,導致座標與原圖不符。

3. 關鍵坑點:前端顯示尺寸 ≠ 原圖尺寸

問題:前端將圖片 CSS 限制為 300×300 顯示,使用者在 300×300 畫布上選取座標。若原圖為 1200×1200,直接用這些座標裁剪原圖,結果會偏移且縮小 4 倍。

解決方案(推薦流程):

  1. 後端收到原圖 → 檢查尺寸
  2. 若非 300×300 → 生成 300×300 縮略圖(用 ImageUtil.thumbnailImage)
  3. 前端載入此縮略圖進行裁剪,獲得座標
  4. 後端用相同座標裁剪縮略圖(而非原圖)
  5. (可選)裁剪完成後刪除暫存縮略圖

此法確保「前端所見即後端所切」,完全避開座標映射換算麻煩。


完整程式碼下載

原文附件:CSDN 下載連結

原文出處:Java 圖片裁剪和生成縮略圖

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved