J2ME 游戲開發中,Sprite 精靈類可自動處理 PNG 等格式的透明通道。但當需要程序動態繪製圖形(如跑馬燈、粒子特效、UI 組件)並實現透明/半透明效果時,標準 Graphics 無法直接輸出帶 Alpha 的不可變圖片。本文詳解「可變圖片繪製 → 像素提取 → Alpha 處理 → 不可變圖片創建」完整鏈路。
| 方法 | 可變性 | 支持 Alpha | 獲取 Graphics | 典型用途 |
|---|---|---|---|---|
| Image.createImage(w, h) | 可變 | 否(無 Alpha 通道) | 是 | 離屏緩衝、動態繪製 |
| Image.createRGBImage(rgb[], w, h, processAlpha) | 不可變 | 是(processAlpha=true) | 否 | 最終渲染、Sprite 素材 |
int w = 32, h = 24;
Image mutableImg = Image.createImage(w, h); // 可變圖片
Graphics g = mutableImg.getGraphics();
g.setColor(0xFFFFFF);
g.fillRect(0, 0, w, h); // 白色背景(後續將設置為透明)
g.setColor(0xFF0000);
g.fillRect(10, 10, 20, 20); // 繪製紅色方塊作為實際內容
int[] rgbData = new int[w * h];
mutableImg.getRGB(rgbData, 0, w, 0, 0, w, h);
// 參數:目標數組、偏移量、掃描行寬、源坐標 x,y、寬高
像素格式說明:
0x00RRGGBB:高 8 位為 0 → 完全透明0xAARRGGBB:高 8 位為 Alpha (0-255) → 半透明0xFFRRGGBB:高 8 位為 255 → 不透明
int transparentColor = 0x00FFFFFF; // 目標透明色(白色,不含 Alpha)
for (int i = 0; i < rgbData.length; i++) {
// 僅比較 RGB 分量,忽略原有 Alpha
if ((rgbData[i] & 0x00FFFFFF) == transparentColor) {
rgbData[i] = rgbData[i] & 0x00FFFFFF; // 清除高 8 位 → 0x00RRGGBB
}
}
Image immutableImg = Image.createRGBImage(rgbData, w, h, true);
// 最後一個參數 processAlpha=true 啟用 Alpha 通道解析
/**
* 將指定顏色轉為透明色
* @param srcImg 源可變圖片
* @param alphaColor 目標透明色,格式 0x00RRGGBB(不含 Alpha)
* @return 帶 Alpha 通道的不可變圖片
*/
public static Image createAlphaImage(Image srcImg, int alphaColor) {
int w = srcImg.getWidth();
int h = srcImg.getHeight();
int[] rgbData = new int[w * h];
srcImg.getRGB(rgbData, 0, w, 0, 0, w, h);
for (int i = 0; i < rgbData.length; i++) {
if ((rgbData[i] & 0x00FFFFFF) == alphaColor) {
rgbData[i] = rgbData[i] & 0x00FFFFFF; // 設置 Alpha=0
}
}
return Image.createRGBImage(rgbData, w, h, true);
}
g.setColor(0x80FF0000)(半透明紅),無需後處理。Graphics,最後統一 createAlphaImage。int[] rgbData 數組對象,避免頻繁 GC;大圖片考慮分塊處理。mutableImg.getGraphics() 無法設置 Alpha,繪製出的圖片無透明效果。processAlpha 參數:傳 false 會丟棄 Alpha 通道,圖片變不透明。J2ME 透明圖片繪製的本質是利用可變圖片作為畫布,不可變圖片作為最終渲染載體。掌握 getRGB/createRGBImage 的 ARGB 像素協議與 processAlpha 開關,即可實現任意程序生成圖形的透明/半透明效果,突破 Sprite 依賴靜態資源文件的限制。