Java 2D API 提供強大的圖像合成與繪圖能力。本文以 BufferedImage 為核心,詳細講解內存圖像創建、像素級操作、透明度控制、渲染提示調優、Sprite 動畫實現全流程,並附完整 Applet 示例代碼。
int width = 200, height = 300;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// TYPE_INT_ARGB: 32位像素 = 8位Alpha + 8位R + 8位G + 8位B
Graphics2D g2d = image.createGraphics(); // 獲得繪圖上下文
// 使用 g2d 繪製形狀、圖像、文本、應用變換...
g2d.dispose(); // 用完釋放資源
TYPE_INT_ARGB 支持 Alpha 通道,是透明圖像處理的首選類型。每像素佔 4 字節,200×300 圖像約 240KB,極輕量。
// 讀取單個像素 (返回 ARGB 打包 int)
int pixel = image.getRGB(x, y);
int alpha = (pixel >> 24) & 0xFF;
int red = (pixel >> 16) & 0xFF;
int green = (pixel >> 8) & 0xFF;
int blue = pixel & 0xFF;
// 批量讀取區域像素
int[] pixels = image.getRGB(startX, startY, w, h, null, 0, w);
// 設置單個像素
image.setRGB(x, y, (alpha<<24) | (red<<16) | (green<<8) | blue);
// 批量設置
image.setRGB(startX, startY, w, h, pixels, 0, w);
像素操作是圖像濾鏡、特效、分析的基礎。
繪製 Sprite 時需背景全透明:
// 1. 設置 CLEAR 合成規則:輸出像素 = 0 (完全透明)
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
// 2. 填充整個圖像區域
g2d.fill(new Rectangle2D.Double(0, 0, spriteSize, spriteSize));
// 3. 恢復默認 SRC_OVER 合成繪製實際圖形
g2d.setComposite(AlphaComposite.SrcOver);
CLEAR 規則忽略顏色,直接將像素 Alpha 置 0。此技巧廣泛用於遊戲精靈、UI 圖標、水印合成。
// Alpha 合成插值質量:最高質量
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
// 常用提示鍵與值
KEY_ANTIALIASING -> VALUE_ANTIALIAS_ON/OFF/DEFAULT // 抗鋸齒
KEY_COLOR_RENDERING -> VALUE_COLOR_RENDER_SPEED/QUALITY // 顏色渲染
KEY_DITHERING -> VALUE_DITHER_ENABLE/DISABLE // 抖動
KEY_FRACTIONALMETRICS -> VALUE_FRACTIONALMETRICS_ON/OFF // 文本度量
KEY_INTERPOLATION -> VALUE_INTERPOLATION_BICUBIC/BILINEAR/NEAREST_NEIGHBOR // 圖像縮放插值
KEY_RENDERING -> VALUE_RENDERING_SPEED/QUALITY // 通用渲染
KEY_TEXT_ANTIALIASING -> VALUE_TEXT_ANTIALIASING_ON/OFF // 文本抗鋸齒
默認值視平台而定。高質量渲染適合離線生成圖片;實時動畫/遊戲優先速度。
double totalAngle; // 精靈整體旋轉角度
double spriteAngle; // 精靈自旋角度
ImagePanel imagePanel; // 顯示面板
BufferedImage sprite; // 精靈圖像
int spriteSize = 100; // 精靈尺寸
Ellipse2D.Double circle; // 組成元素:圓
Line2D.Double line; // 組成元素:線
Color[] colors = {Color.red, Color.yellow, Color.green, Color.blue,
Color.cyan, Color.pink, Color.magenta, Color.orange};
Timer timer;
long interval = 50; // 重繪間隔 ms
BufferedImage createSprite(int size) {
BufferedImage sprite = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = sprite.createGraphics();
// 渲染提示
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
// 透明背景
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
g2d.fill(new Rectangle2D.Double(0, 0, size, size));
g2d.setComposite(AlphaComposite.SrcOver);
// 幾何對象
circle = new Ellipse2D.Double(0, 0, size*0.8, size*0.8);
line = new Line2D.Double(size*0.1, size*0.5, size*0.9, size*0.5);
// 繪製 8 組旋轉圓+線
for (int i = 0; i < 8; i++) {
g2d.rotate(Math.PI / 4); // 每次旋轉 45°
g2d.setColor(colors[i]);
g2d.fill(circle);
g2d.draw(line);
}
g2d.dispose();
return sprite;
}
利用坐標系旋轉 g2d.rotate() 而非計算座標,極大簡化重複圖形繪製。
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
totalAngle += Math.PI / 16; // 整體公轉
spriteAngle += Math.PI / 8; // 自旋
imagePanel.repaint(); // 觸發重繪
}
}, 0, interval);
class ImagePanel extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// 繪製背景 Logo...
// 繪製 Sprite:平移到中心、應用旋轉、畫圖
g2d.translate(getWidth()/2, getHeight()/2);
g2d.rotate(totalAngle);
g2d.translate(-spriteSize/2, -spriteSize/2);
g2d.drawImage(sprite, 0, 0, this);
}
}
| 技術點 | 核心類/方法 | 應用場景 |
|---|---|---|
| 內存圖像創建 | BufferedImage 构造函数、TYPE_INT_ARGB | 動態生成圖標、圖表、水印、遊戲精靈 |
| 圖形上下文 | createGraphics() → Graphics2D | 所有繪製操作入口 |
| 透明背景 | AlphaComposite.CLEAR + fill() | 非矩形圖像、疊加合成 |
| 渲染提示 | setRenderingHint(KEY, VALUE) | 質量/速度權衡、抗鋸齒、插值算法 |
| 坐標系變換 | translate/rotate/scale/shear | 複雜圖形重複繪製、動畫變換 |
| 像素操作 | getRGB/setRGB | 濾鏡、圖像分析、數據隱寫 |
| 動畫驅動 | Timer + repaint() / AnimationTimer | 遊戲循環、UI 動效 |
掌握 BufferedImage + Graphics2D 組合,即掌握了 Java 2D 繪圖的靈魂。從簡單圖表生成到複雜遊戲引擎渲染,核心原理皆在此。