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

Java 圖片合併實戰:基於 BufferedImage 實現多圖拼接

     編輯:Java 相關知識

前言

在 Java 開發中,圖片拼接是常見需求(如生成海報、拼接驗證碼、合併掃描件)。本文通過完整代碼示例,演示如何使用 java.awt.image.BufferedImage 與 javax.imageio.ImageIO 實現多張圖片的水平、垂直或網格拼接,並解析關鍵 API 用法與避坑指南。

核心思路

  1. 讀取源圖片為 BufferedImage 對象
  2. 獲取圖片寬高,創建目標畫布 BufferedImage
  3. 提取源圖片 RGB 像素數組(getRGB())
  4. 將像素數組寫入目標畫布指定區域(setRGB())
  5. 輸出合成圖片(ImageIO.write())

完整代碼示例

package com.test;

import java.io.File;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

public class ImageCombineTest {
    public static void main(String[] args) {
        try {
            // 1. 讀取第一張圖片
            File fileOne = new File("/Users/coolcloud/Pictures/Art/lena-2.jpg");
            BufferedImage imageOne = ImageIO.read(fileOne);
            int width = imageOne.getWidth();
            int height = imageOne.getHeight();

            // 2. 提取第一張圖片 RGB 數據
            int[] imageArrayOne = new int[width * height];
            imageArrayOne = imageOne.getRGB(0, 0, width, height, imageArrayOne, 0, width);

            // 3. 讀取第二張圖片(此處為演示使用同一張)
            File fileTwo = new File("/Users/coolcloud/Pictures/Art/lena-2.jpg");
            BufferedImage imageTwo = ImageIO.read(fileTwo);
            int[] imageArrayTwo = new int[width * height];
            imageArrayTwo = imageTwo.getRGB(0, 0, width, height, imageArrayTwo, 0, width);

            // 4. 創建目標畫布:寬度翻倍,高度不變(水平拼接)
            // 若需垂直拼接:new BufferedImage(width, height * 2, BufferedImage.TYPE_INT_RGB)
            // 若需 2x2 網格:new BufferedImage(width * 2, height * 2, BufferedImage.TYPE_INT_RGB)
            BufferedImage imageNew = new BufferedImage(width * 2, height, BufferedImage.TYPE_INT_RGB);

            // 5. 寫入像素數據
            // 左半部分
            imageNew.setRGB(0, 0, width, height, imageArrayOne, 0, width);
            // 右半部分
            imageNew.setRGB(width, 0, width, height, imageArrayTwo, 0, width);

            // 6. 輸出文件
            File outFile = new File("/Users/coolcloud/Pictures/combined_pic.jpg");
            ImageIO.write(imageNew, "jpg", outFile); // 格式建議與源圖一致
            System.out.println("圖片合併成功:" + outFile.getAbsolutePath());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

關鍵 API 解析

方法說明
ImageIO.read(File)讀取圖片文件為 BufferedImage,支持 JPG/PNG/BMP/GIF 等格式
getRGB(x, y, w, h, rgbArray, offset, scansize) 提取指定矩形區域的像素值到一維數組(ARGB 格式,每像素佔 1 int)
setRGB(x, y, w, h, rgbArray, offset, scansize) 將像素數組寫入畫布指定矩形區域
new BufferedImage(w, h, type) 創建畫布,type 常用 TYPE_INT_RGB(無透明通道)或 TYPE_INT_ARGB(含透明)
ImageIO.write(img, format, file) 將圖片按指定格式寫入文件/流

常見拼接模式坐標計算

  • 水平拼接 N 張: 畫布寬 = Σ寬度,高 = max(高度)。第 i 張起始 x = Σj<i width_j
  • 垂直拼接 N 張: 畫布高 = Σ高度,寬 = max(寬度)。第 i 張起始 y = Σj<i height_j
  • 網格拼接(行列固定): 畫布寬 = 列數 × 最大寬,高 = 行數 × 最大高。按行列索引計算 (x, y)

避坑指南與最佳實踐

  1. 圖片尺寸不一致: 拼接前統一縮放至相同尺寸,或按最大尺寸創建畫布並在目標區域居中繪製(需用 Graphics2D.drawImage() 而非像素拷貝)。
  2. 透明通道丟失: 源圖含透明通道時,畫布類型必須用 TYPE_INT_ARGB,否則透明區變黑。
  3. 內存溢出風險: 大圖拼接像素數組佔用大量堆內存,建議分塊處理或使用 Graphics2D 流式繪製。
  4. 色彩空間差異: 部分圖片為 CMYK 模式,讀取後顏色異常,需轉換為 sRGB。
  5. 文件格式選擇: 照片類用 JPG(有損壓縮、體積小);截圖/文字類用 PNG(無損、支持透明)。

進階:使用 Graphics2D 實現更靈活的拼接

BufferedImage canvas = new BufferedImage(totalWidth, totalHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = canvas.createGraphics();
// 可設置渲染提示:抗鋸齒、插值算法等
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(imageOne, 0, 0, null);
g2d.drawImage(imageTwo, width, 0, null);
g2d.dispose(); // 必須釋放資源
ImageIO.write(canvas, "png", outFile);

Graphics2D 方式支持旋轉、縮放、透明度混合、濾鏡等高級操作,適合複雜合成場景。

總結

基於 BufferedImage 像素級操作適合簡單、固定布局的拼接;Graphics2D 更適合動態、複雜的圖形合成。實際項目中應根據圖片大小、數量、性能要求選擇方案,並做好異常處理與資源釋放。

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