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

Java 圖片處理工具類完整指南:縮放、切割、水印、格式轉換一站式實現

     編輯:Java 程式設計入門

前言:為什麼需要一個通用的圖片處理工具類?

在 Java 企業級開發中,圖片處理是高頻需求:用戶頭像裁剪、商品圖縮略圖生成、版權水印添加、格式轉換等。雖然 Java AWT/ImageIO 提供了底層 API,但直接調用代碼冗長、參數繁雜、易出錯。封裝一個功能完善、參數靈活、異常處理完善的 ImageUtils 工具類,能顯著提升開發效率與代碼可維護性。

本文提供一個生產級可用的工具類完整實現,涵蓋縮放、切割、格式轉換、灰度化、文字/圖片水印六大核心功能,並附帶詳細參數說明與測試範例。

一、工具類核心架構與常量定義

public class ImageUtils {
    // 支援的圖片格式常量
    public static final String IMAGE_TYPE_GIF = "gif";
    public static final String IMAGE_TYPE_JPG = "jpg";
    public static final String IMAGE_TYPE_JPEG = "jpeg";
    public static final String IMAGE_TYPE_BMP = "bmp";
    public static final String IMAGE_TYPE_PNG = "png";
    public static final String IMAGE_TYPE_PSD = "psd";
    // ... 方法定義
}

統一常量管理,避免硬編碼字串散落,方便擴展新格式。

二、六大核心功能詳細實現

1. 圖片縮放(支援按比例 / 指定寬高)

方法一:按比例縮放 scale()

/**
 * @param srcImageFile 源圖路徑
 * @param result 目標路徑
 * @param scale 縮放倍數(如 2 表示 2 倍)
 * @param flag true=放大, false=縮小
 */
public static void scale(String srcImageFile, String result, int scale, boolean flag)

使用 Image.getScaledInstance() 實現,簡單高效,適合等比例縮放場景。

方法二:指定寬高縮放 scale2()(支援補白)

/**
 * @param height 目標高度
 * @param width 目標寬度
 * @param bb true=保持比例並補白, false=強制拉伸
 */
public static void scale2(String srcImageFile, String result, int height, int width, boolean bb)

核心邏輯:

  • 計算縮放比例 ratio = min(targetW/srcW, targetH/srcH),保持原圖比例。
  • 使用 AffineTransformOp 進行高質量縮放(SCALE_SMOOTH)。
  • bb=true 時,建立白色畫布,將縮放後圖片置中繪製,實現「含邊框的縮略圖」。

2. 圖片切割(三種模式全覆蓋)

模式一:指定座標區域切割 cut()

public static void cut(String src, String dest, int x, int y, int width, int height)

使用 CropImageFilter + FilteredImageSource 實現精確區域截取。

模式二:按行列數均分切割 cut2()

public static void cut2(String src, String destDir, int rows, int cols)

自動計算每塊寬高,雙層循環輸出 _r{i}_c{j}.jpg,適合大圖分片、拼圖遊戲素材生成。

模式三:指定塊大小切割 cut3()

public static void cut3(String src, String destDir, int destWidth, int destHeight)

根據目標塊尺寸自動推算行列數,邊緣不足一塊時自動補齊。

3. 格式轉換 convert()

public static void convert(String src, String formatName, String dest)

一行核心代碼:ImageIO.write(src, formatName, new File(dest))。支援 JPG↔PNG、GIF→JPG、BMP→PNG 等互轉。注意:JPG 不支援透明通道,轉換時透明區域會變黑/白。

4. 彩色轉灰度 gray()

ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp op = new ColorConvertOp(cs, null);
src = op.filter(src, null);

利用 ColorConvertOp 進行色彩空間轉換,效能優於像素級手動運算。

5. 文字水印 pressText() / pressText2()

/**
 * @param fontName 字體名(如「微軟雅黑」)
 * @param fontStyle Font.BOLD / Font.ITALIC
 * @param color 字體顏色
 * @param fontSize 字號
 * @param x, y 位置微調偏移量
 * @param alpha 透明度 0.0f~1.0f
 */
public static void pressText(String text, String src, String dest, 
    String fontName, int fontStyle, Color color, int fontSize, 
    int x, int y, float alpha)

關鍵技術點:

  • AlphaComposite.SRC_ATOP 實現透明度混合。
  • getLength() 估算中英文混排寬度(中文按 2 字符計),實現文字置中。
  • 兩個重載方法參數順序略有差異,建議統一使用第一個。

6. 圖片水印 pressImage()

public static void pressImage(String pressImg, String src, String dest, 
    int x, int y, float alpha)

將水印圖讀取為 Image,計算置中座標 (w-wm)/2, (h-hm)/2,疊加繪製。支援 PNG 透明水印(需源圖為 TYPE_INT_ARGB)。

三、完整測試範例(main 方法)

public static void main(String[] args) {
    // 1. 縮放測試
    ImageUtils.scale("e:/abc.jpg", "e:/abc_scale.jpg", 2, true);      // 放大 2 倍
    ImageUtils.scale2("e:/abc.jpg", "e:/abc_scale2.jpg", 500, 300, true); // 限制 500x300 補白

    // 2. 切割測試
    ImageUtils.cut("e:/abc.jpg", "e:/abc_cut.jpg", 0, 0, 400, 400);   // 截取左上 400x400
    ImageUtils.cut2("e:/abc.jpg", "e:/", 2, 2);                       // 2x2 均分
    ImageUtils.cut3("e:/abc.jpg", "e:/", 300, 300);                   // 300x300 分塊

    // 3. 格式轉換
    ImageUtils.convert("e:/abc.jpg", "GIF", "e:/abc_convert.gif");

    // 4. 灰度化
    ImageUtils.gray("e:/abc.jpg", "e:/abc_gray.jpg");

    // 5. 文字水印
    ImageUtils.pressText("我是水印", "e:/abc.jpg", "e:/abc_wm1.jpg", "微軟雅黑", Font.BOLD, Color.WHITE, 30, 0, 0, 0.5f);
    ImageUtils.pressText2("另一種方式", "e:/abc.jpg", "e:/abc_wm2.jpg", "黑體", 36, Color.RED, 40, 10, 10, 0.7f);

    // 6. 圖片水印
    ImageUtils.pressImage("e:/logo.png", "e:/abc.jpg", "e:/abc_wm3.jpg", 0, 0, 0.6f);
}

四、生產環境優化建議

問題解決方案
JPG 輸出預設無壓縮品質控制引入 ImageWriteParam 設定 compressionQuality (0.7f~0.9f)
大圖處理 OOM 風險使用 ImageReader.setInput() 串流讀取、分塊處理;或引入 TwelveMonkeys/ImageMagick
字體跨平台缺失(Linux 無微軟雅黑)專案打包 .ttf 字體檔,用 Font.createFont() 動態載入
水印位置支援九宮格/平鋪新增 position 參數枚舉,計算座標邏輯
並發效能瓶頸引入 ThreadPoolExecutor 異步處理,或使用 Thumbnailator 庫替代

五、現代化替代方案:Thumbnailator

若專案允許引入第三方庫,強烈推薦 Thumbnailator:

<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.20</version>
</dependency>

// 一行代碼完成縮放+水印+輸出
Thumbnails.of("input.jpg")
    .size(800, 600)
    .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("logo.png")), 0.5f)
    .outputQuality(0.85f)
    .toFile("output.jpg");

優點:API 流暢、自動處理旋轉/EXIF、支援串流、記憶體優化、維護活躍。

結語

本文提供的 ImageUtils 類雖基於原生 AWT,但功能完整、參數靈活,足以應對多數中小型專案的圖片處理需求。理解其內部原理(Graphics2D、AffineTransform、ImageFilter)有助於排查疑難雜症。對於高併發、大圖、複雜水印場景,建議遷移至 Thumbnailator 或圖片處理微服務(如基於 ImageMagick/OpenCV),實現計算與業務解耦。

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