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

Java 圖片處理實戰:純 Java 與 Jmagick (ImageMagick) 雙方案對比與完整工具類

     編輯:Java 相關知識

Java 圖片處理常見需求:等比縮放、水印(圖片/文字)、裁剪。純 Java 方案 (ImageIO + BufferedImage) 部署簡單但畫質一般、大圖易 OOM;Jmagick 封裝 ImageMagick 原生庫,畫質優、支援格式多、效能強,但需部署原生庫。本文提供兩套完整工具類代碼與 Jmagick Windows 部署避坑指南。

方案對比

維度純 Java (ImageIO)Jmagick (ImageMagick)
部署複雜度零依賴,跨平台需安裝 ImageMagick + JNI dll/so,配置 java.library.path
畫質(縮放)雙線性/雙三次,中等Lanczos/Sinc 等高級濾波器,專業級
格式支援JPEG/PNG/BMP/GIF/WBMP200+ 格式 (含 PSD、HEIC、RAW、SVG、PDF)
大圖處理全量載入堆內存,易 OOM串流處理、磁盤快取,支援 GB 級大圖
水印/特效需手繪 Graphics2D內建 composite、annotate、morphology、distort
執行緒安全安全ImageMagick 6.x 非線程安全,需同步或用 7.x

純 Java 等比縮放工具類

public static void resize(File img, int maxW, int maxH) throws IOException {
    BufferedImage src = ImageIO.read(img);
    int w = src.getWidth(), h = src.getHeight();
    if (w <= maxW && h <= maxH) return;

    double scale = Math.min((double) maxW / w, (double) maxH / h);
    int nw = (int) (w * scale), nh = (int) (h * scale);

    BufferedImage dst = new BufferedImage(nw, nh, BufferedImage.TYPE_3BYTE_BGR);
    dst.getGraphics().drawImage(src.getScaledInstance(nw, nh, Image.SCALE_SMOOTH), 0, 0, null);

    try (FileOutputStream fos = new FileOutputStream(img)) {
        ImageIO.write(dst, "jpg", fos);  // 或按原格式
    }
}

Jmagick 完整工具類 (核心方法)

public class ImageUtils {
    static { System.setProperty("jmagick.systemclassloader", "no"); }

    // 等比縮放
    public static void changeSize(String src, String dst, int maxW, int maxH) {
        ImageInfo info = new ImageInfo(src);
        MagickImage img = new MagickImage(info);
        Dimension dim = img.getDimension();
        // ... 計算目標尺寸同純 Java ...
        MagickImage scaled = img.scaleImage(nw, nh);
        scaled.setFileName(dst);
        scaled.writeImage(info);
        scaled.destroyImages();
    }

    // 圖片水印 (右下角)
    public static void watermarkImage(String src, String dst, String logo) {
        MagickImage base = new MagickImage(new ImageInfo(src));
        MagickImage mark = new MagickImage(new ImageInfo(logo));
        mark = mark.scaleImage(base.getDimension().width/8, -1); // 等比
        base.compositeImage(CompositeOperator.AtopCompositeOp, mark,
                base.getDimension().width - mark.getDimension().width - 10,
                base.getDimension().height - mark.getDimension().height - 10);
        base.setFileName(dst);
        base.writeImage(new ImageInfo());
        base.destroyImages(); mark.destroyImages();
    }

    // 文字水印 (右下角)
    public static void watermarkText(String src, String dst, String text) {
        MagickImage img = new MagickImage(new ImageInfo(src));
        DrawInfo di = new DrawInfo(new ImageInfo(src));
        di.setFill(PixelPacket.queryColorDatabase("white"));
        di.setUnderColor(new PixelPacket(0,0,0,100)); // 半透明黑底
        di.setPointsize(12);
        di.setTextAntialias(true);
        di.setGravity(Gravity.SOUTHEAST);
        di.setText(" " + text + " 上傳於 " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        img.annotateImage(di);
        img.setFileName(dst);
        img.writeImage(new ImageInfo());
        img.destroyImages();
    }

    // 裁剪
    public static void crop(String src, String dst, int x, int y, int w, int h) {
        MagickImage img = new MagickImage(new ImageInfo(src));
        MagickImage cropped = img.cropImage(new Rectangle(x, y, w, h));
        cropped.setFileName(dst);
        cropped.writeImage(new ImageInfo(src));
        cropped.destroyImages(); img.destroyImages();
    }
}

Jmagick Windows 部署避坑清單 (ImageMagick 6.4.x + Jmagick 6.3.9)

  1. 安裝 ImageMagick:ImageMagick-6.4.6-4-Q16-windows-dll.exe,**勾選「Add to system path」**。
  2. 將安裝目錄所有 *.dll 複製到 C:\Windows\System32\ (或 SysWOW64)。
  3. 解壓 jmagick-win-6.3.9-q16.zip,將 jmagick.dll 複製到 System32 與 JDK/bin。
  4. jmagick.jar 放入 WEB-INF/lib 與 Tomcat/lib。
  5. Tomcat catalina.bat 增加堆設定:set JAVA_OPTS=-Xms256m -Xmx768m -XX:MaxPermSize=128m (JDK 8 以前)。
  6. 代碼靜態塊**必須**設定:System.setProperty("jmagick.systemclassloader", "no"); 否則拋 UnsatisfiedLinkError。

現代替代建議

  • 純 Java:TwelveMonkeys ImageIO (擴充格式)、Thumbnailator (簡潔 API)、ImgScalr。
  • 原生加速:ImageMagick 7 + JNA (無 JNI 編譯)、GraphicsMagick + gm4java、libvips + libvips-java (極速、低記憶體)。
  • 雲原生:對象存儲 (S3/OSS) 內建圖片處理參數 (如 ?x-oss-process=image/resize,w_200) 卸載應用層。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved