Java Servlet 圖片處理專案實作 (一)

Java Servlet 圖片處理專案實作,指定圖片尺寸,不進行 zip 壓縮,單純回傳一張新圖片 (SingleImageResize) 篇。

java image project
開新專案

我們開一個專案命名為 "image-resize",開專案方法請參考 圖解 IntelliJ 開新 Maven 專案。 設定好 Tomcat 環境,請參考這篇

Servlet Entry

我們打算建立三個 Servlet 來使用者的要求, 分別的功能是:

  • 單檔改變尺寸,不進行 zip 壓縮,單純回傳一張新圖片
  • 預設壓縮圖片壓縮,壓縮成三種大小包在一個 zip 檔案中輸出給使用者。
  • 自定要壓縮的圖片張數、尺寸,壓縮完成後輸出成一個 zip 檔案給使用者。
單檔改變尺寸 (SingleFileResize)
.
├── image-resize.iml
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── judysocute
│   │   │           ├── ResizeInfo.java
│   │   │           └── SingleImageResize.java
│   │   ├── resources
│   │   └── webapp
│   │       └── SingleImageResize.html

簡易 HTML 表單 SingleImageResize.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>單個圖片指定縮放尺寸</title>
</head>
<body>
  <form
    action="single-file-resize"
    method="POST"
    enctype="multipart/form-data"
  >
    <p>選擇圖片</p>
    <input type="file" name="imageFile">
    <p>指定尺寸(格式: 60x60 120x200)</p>
    <input type="text" name="resize">

    <button type="submit">送出</button>
  </form>
</body>
</html>

圖片寬高資訊物件 ResizeInfo.java

/**
 * 要輸出的圖片寬高資訊
 */
class ResizeInfo {
    // 要輸出的寬
    public int m_width;
    // 要輸出的高
    public int m_height;

    /**
     * @param sSize {String} - 字串通常是 60x60 120x200 這種格式
     */
    ResizeInfo(String sSize) {
        this(sSize.split("x"));
    }

    ResizeInfo(String[] spSize) {
        m_width = Integer.parseInt(spSize[0]);
        m_height = Integer.parseInt(spSize[1]);
    }
}

Servlet 物件 SingleImageResize.java

@MultipartConfig() // 這個是為了要使用 getPart() 方法一定要加的哦!
@WebServlet(
        name = "SingleFileResize",
        urlPatterns = {"/single-file-resize"}, // servlet entry url
        loadOnStartup = 1
)
public class SingleImageResize extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String size = req.getParameter("resize"); // 接收使用者指定的圖片尺寸
        ResizeInfo resizeInfo = new ResizeInfo(size); // 字串格式是 60x60 120x200 這種格式,轉為 ResizeInfo 物件

        Part imagePart = req.getPart("imageFile");

        String fileName = imagePart.getSubmittedFileName(); // 使用者上傳的檔名
        String formatName = fileName.substring(fileName.lastIndexOf(".") + 1); // 副檔名(拿原圖的副檔名就好)

        BufferedImage bufferedImage = ImageIO.read(imagePart.getInputStream());

        // 建立一個空白的 BufferedImage 物件,
        // 寬度、高度 為使用者輸入的
        // 輸出類型為使用者上傳的圖片類型
        BufferedImage exportBFImage = new BufferedImage(resizeInfo.m_width, resizeInfo.m_height, bufferedImage.getType());

        // 用剛才建立的空白 BufferedImage 物件來建立畫布
        Graphics2D g2d = exportBFImage.createGraphics();
        g2d.drawImage(
                bufferedImage, // 把我們讀入的圖片畫上去
                0, // x軸起始點
                0, // y軸起始點
                resizeInfo.m_width, // 要畫上去的寬度
                resizeInfo.m_height, // 要畫上去的長度
                null
        );
        g2d.dispose(); // g2d 就不再接受被寫入內容

        // Servlet 輸出流,用於輸出檔案給用戶
        ServletOutputStream out = resp.getOutputStream();

        // 設定回應格式 "image/jpeg" or "image/png" ...
        resp.setContentType("image/" + formatName);
        ImageIO.write(exportBFImage, formatName, out);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // "/" 開頭帶表從我們 Smart Tomcat 定義的 Deployment Directory 開始
        // 也就是 webapp 那個目錄找檔案
        RequestDispatcher view = req.getRequestDispatcher("/SingleImageResize.html");

        // 轉回去給使用者
        view.forward(req, resp);
    }
}

這次專案的程式碼就有上 github 了! 歡迎拉下來看看! https://github.com/judysocute/image-resize