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

Java 圖片壓縮完整實戰:等比縮放、固定尺寸與質量控制

     編輯:Java 相關知識

核心需求場景

  • 用戶上傳頭像/附件,需限制檔案大小與尺寸
  • 生成縮圖用於列表展示,節省頻寬與載入時間
  • 批量處理圖片存儲,控制磁碟佔用

ImageProcess 工具類設計

public class ImageProcess {
    private Image img;
    private int width, height;
    private String imageFormat;

    public ImageProcess(InputStream in, String fileName) throws Exception {
        img = ImageIO.read(in);
        width = img.getWidth(null);
        height = img.getHeight(null);
        imageFormat = fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    /** 智能壓縮:根據長寬比自動選擇以寬或高為基準 */
    public byte[] resizeFix(int maxW, int maxH) throws IOException {
        return (width * 1.0 / height > maxW * 1.0 / maxH)
                ? resizeByWidth(maxW) : resizeByHeight(maxH);
    }

    /** 以寬度為基準等比縮放 */
    public byte[] resizeByWidth(int w) throws IOException {
        int h = (int) (height * w / (double) width);
        return resize(w, h);
    }

    /** 以高度為基準等比縮放 */
    public byte[] resizeByHeight(int h) throws IOException {
        int w = (int) (width * h / (double) height);
        return resize(w, h);
    }

    /** 強制縮放至固定尺寸(可能變形) */
    public byte[] resize(int w, int h) throws IOException {
        BufferedImage target = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        target.getGraphics().drawImage(img, 0, 0, w, h, null);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(target, imageFormat, baos);
        return baos.toByteArray();
    }
}

關鍵技術點解析

  1. BufferedImage.TYPE_INT_RGB:標準 RGB 模型,適合 JPEG 輸出。若需透明背景請用 TYPE_INT_ARGB。
  2. Graphics.drawImage(img, 0, 0, w, h, null):核心縮放繪製,SCALE_SMOOTH 隱含於 ImageIO.write 編碼器中。
  3. ByteArrayOutputStream:內存流輸出,避免臨時文件 I/O,適合 Web 上傳直傳對象存儲。
  4. 格式保持:自動從原文件名解析副檔名(jpg/png/gif/bmp),保持原格式輸出。

進階優化建議

  • 質量控制:JPEG 輸出時可用 ImageWriteParam 設置壓縮質量(0.7-0.9 平衡點)
  • 大圖分塊處理:超大圖(>5000px)建議使用 ImageReader 分塊讀取,避免 OOM
  • 並發處理:配合 CompletableFuture 或線程池批量壓縮
  • 第三方庫:Thumbnailator、TwelveMonkeys ImageIO 提供更豐富的格式支援與元數據保留

使用示例

// Controller 層
@PostMapping("/upload")
public ResponseEntity<String> upload(@RequestParam MultipartFile file) {
    try (InputStream in = file.getInputStream()) {
        ImageProcess processor = new ImageProcess(in, file.getOriginalFilename());
        byte[] compressed = processor.resizeFix(800, 600); // 限制長邊 800px
        // 上傳至 OSS / 保存至資料庫 BLOB
        return ResponseEntity.ok("success");
    } catch (Exception e) {
        return ResponseEntity.status(500).body("圖片處理失敗");
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved