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

Java 實作圖片上傳與九宮格切割:基於 ImageIO 的完整方案

     編輯:Java 相關知識

針對部門 Logo 需適應瀏覽器相容與拉伸需求,本文示範如何利用 javax.imageio.ImageReader 將上傳圖片切割為左、中、右三段與保留區,並以 Blob 存入資料庫,最後透過 CSS 精靈技術無縫拼合顯示。

前端表單關鍵點

<form method="post" enctype="multipart/form-data">
  <input type="file" name="logoFile" id="logoFile" onchange="checkFile()" />
  <input type="hidden" name="suffix" id="suffix" />
</form>

JS checkFile() 驗證副檔名 (jpg/jpeg/gif/bmp/png) 並寫入 hidden 欄位,供後端判斷格式。

後端核心邏輯

1. 取得 ImageReader 與圖片串流

Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(suffix);
ImageReader reader = readers.next();
InputStream in = new BufferedInputStream(new FileInputStream(logoFile));
ImageInputStream iis = ImageIO.createImageInputStream(in);
reader.setInput(iis, true);
int imgW = reader.getWidth(0);
int imgH = 80; // 固定高度

2. 定義切割區域 (Rectangle)

int leftW   = imgW / 2;
int midW    = (imgW - leftW) / 3;
int rightW  = 5;
int retainW = imgW - leftW - midW - rightW;

Rectangle leftRect   = new Rectangle(0, 0, leftW, imgH);
Rectangle midRect    = new Rectangle(leftW, 0, midW, imgH);
Rectangle rightRect  = new Rectangle(leftW + midW, 0, rightW, imgH);
Rectangle retainRect = new Rectangle(leftW + midW + rightW, 0, retainW, imgH);

3. 逐區讀取、轉 ByteArrayOutputStream、包裝 Blob

ImageReadParam param = reader.getDefaultReadParam();
ByteArrayOutputStream baos = new ByteArrayOutputStream();

param.setSourceRegion(leftRect);
BufferedImage bi = reader.read(0, param);
ImageIO.write(bi, suffix, baos);
Blob leftBlob = Hibernate.createBlob(baos.toByteArray(), session);
baos.reset(); // 重複使用,減少物件建立
// ... 依序處理 midRect, rightRect, retainRect

4. 儲存至 DepartmentLogo 實體

logo.setLeftPartImage(leftBlob);
logo.setMiddlePartImage(midBlob);
logo.setRightPartImage(rightBlob);
logo.setRetainPartImage(retainBlob);
logo.setSuffix(suffix);
departmentManager.save(department);

前端 CSS 精靈拼合顯示

<style>
#leftLogo   { background: url(showLogo.action?position=left) no-repeat; width: ${leftW}px; height: 80px; }
#midLogo    { background: url(showLogo.action?position=middle) no-repeat; width: ${midW}px; height: 80px; }
#rightLogo  { background: url(showLogo.action?position=right) repeat-x; height: 80px; }
#retainLogo { background: url(showLogo.action?position=retain) no-repeat; width: ${retainW}px; height: 80px; }
</style>

<div id="leftLogo"></div>
<div id="midLogo"></div>
<div id="rightLogo"></div>
<div id="retainLogo"></div>

Stream 回傳圖片資料

@Result(name="showLogo", type="stream",
  params={"contentType", "image/jpeg,image/png,image/gif",
          "inputName", "imageLogo", "bufferSize", "4096"})
public String showLogo() {
  String pos = request.getParameter("position");
  Blob blob = switch(pos) {
    case "left" -> logo.getLeftPartImage();
    case "middle" -> logo.getMiddlePartImage();
    case "right" -> logo.getRightPartImage();
    case "retain" -> logo.getRetainPartImage();
    default -> null;
  };
  imageLogo = blob.getBinaryStream();
  return "showLogo";
}

寬度動態獲取

選單載入時讀取 Blob 寬度存入 request 屬性,EL 表達式 ${leftWidth} 直接輸出至 CSS。

總結

方案利用 ImageReader.read(param) 精準切割、ByteArrayOutputStream 記憶體流轉 Blob、Struts2 Stream Result 直輸二進位,完整解決「上傳→切割→存儲→動態寬度→精靈拼合」全鏈路需求。

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