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

J2ME 圖片漸變透明效果實作:像素級 Alpha 通道動畫

     編輯:J2ME

透明/漸變效果是遊戲與 UI 開發常見需求。本文展示如何在 J2ME 中直接操作像素陣列,實現圖片從全透明逐漸顯示為原始不透明度的動畫效果。

核心原理

  • J2ME Image.getRGB() 可取得像素陣列,格式為 0xAARRGGBB(32 位整數,高 8 位為 Alpha)
  • 建立影子像素陣列 shadowRgbImage,初始 Alpha 全為 0(全透明)
  • 每幀將影子像素的 Alpha 向原始像素 Alpha 靠近 +1,直到完全一致
  • 使用 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;
            }
        }
    }
}

關鍵技術點

  1. 像素格式 0xAARRGGBB:位操作提取/設定 Alpha:(pixel >>> 24) & 0xFF 取 Alpha,(alpha << 24) | (pixel & 0x00FFFFFF) 設 Alpha
  2. drawRGB 參數:drawRGB(int[] rgb, offset, scanlength, x, y, w, h, processAlpha),processAlpha=true 才會處理透明度
  3. 記憶體考量:兩個 int[] 佔用 2 * w * h * 4 bytes,大圖片需注意堆疊限制
  4. 效能優化:可改為每幀處理固定數量像素(如 1000 個),避免大圖單幀運算過久導致卡頓

擴展應用

  • 淡入/淡出:雙向 Alpha 插值
  • 局部透明:針對特定區域像素修改 Alpha
  • 遮罩效果:結合另一張灰階圖作為 Alpha 遮罩

像素級操作雖較繁瑣,卻能實現高階 API 無法達到的精細視覺效果,是 J2ME 進階開發的重要技能。

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