透明/漸變效果是遊戲與 UI 開發常見需求。本文展示如何在 J2ME 中直接操作像素陣列,實現圖片從全透明逐漸顯示為原始不透明度的動畫效果。
Image.getRGB() 可取得像素陣列,格式為 0xAARRGGBB(32 位整數,高 8 位為 Alpha)shadowRgbImage,初始 Alpha 全為 0(全透明)Graphics.drawRGB() 直接繪製像素陣列import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import java.io.IOException;
public class ShadowMIDlet extends MIDlet {
private Canvas canvas = new ShadowCanvas();
protected void startApp() {
Display.getDisplay(this).setCurrent(canvas);
}
protected void pauseApp() {}
protected void destroyApp(boolean unconditional) {}
}
class ShadowCanvas extends Canvas implements Runnable {
private int w, h;
private Image srcImage;
private int[] srcRgb; // 原始像素
private int[] shadowRgb; // 漸變像素
private int imgW, imgH;
private int frameCount = 0;
public ShadowCanvas() {
w = getWidth(); h = getHeight();
try {
srcImage = Image.createImage("/av.png"); // 需專案包含此圖片
} catch (IOException e) { e.printStackTrace(); }
imgW = srcImage.getWidth();
imgH = srcImage.getHeight();
// 取得原始像素陣列
srcRgb = new int[imgW * imgH];
srcImage.getRGB(srcRgb, 0, imgW, 0, 0, imgW, imgH);
// 建立影子像素陣列,初始全透明 (Alpha=0)
shadowRgb = new int[srcRgb.length];
System.arraycopy(srcRgb, 0, shadowRgb, 0, shadowRgb.length);
for (int i = 0; i < shadowRgb.length; i++) {
shadowRgb[i] &= 0x00FFFFFF; // 保留 RGB,Alpha 歸零
}
new Thread(this).start();
}
public void paint(Graphics g) {
g.setColor(0x000000);
g.fillRect(0, 0, w, h);
// 繪製漸變圖片(置中)
g.drawRGB(shadowRgb, 0, imgW,
(w - imgW) / 2, (h - imgH) / 2,
imgW, imgH, true);
g.setColor(0x00FF00);
g.drawString("frame=" + frameCount, w/2, 30, Graphics.HCENTER | Graphics.TOP);
}
public void run() {
while (true) {
boolean changed = false;
// 逐像素更新 Alpha
for (int i = 0; i < shadowRgb.length; i++) {
int alpha = (shadowRgb[i] & 0xFF000000) >>> 24; // 目前 Alpha
int targetAlpha = (srcRgb[i] & 0xFF000000) >>> 24; // 目標 Alpha
if (alpha < targetAlpha) {
// Alpha +1,保留原 RGB
shadowRgb[i] = ((alpha + 1) << 24) | (shadowRgb[i] & 0x00FFFFFF);
changed = true;
}
}
try { Thread.sleep(10); } catch (InterruptedException e) {}
frameCount++;
repaint();
// 所有像素達到目標 Alpha,動畫結束
if (!changed) {
System.out.println("漸變動畫結束");
break;
}
}
}
}
(pixel >>> 24) & 0xFF 取 Alpha,(alpha << 24) | (pixel & 0x00FFFFFF) 設 AlphadrawRGB(int[] rgb, offset, scanlength, x, y, w, h, processAlpha),processAlpha=true 才會處理透明度int[] 佔用 2 * w * h * 4 bytes,大圖片需注意堆疊限制像素級操作雖較繁瑣,卻能實現高階 API 無法達到的精細視覺效果,是 J2ME 進階開發的重要技能。