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

SWT/JFace 圖片特效實作:Alpha 漸層與 GIF 動畫播放

     編輯:Java 相關知識

前言

SWT 的 Graphics 體系提供豐富的圖像處理能力。本文展示兩個經典特效:

  1. Alpha 漸層遮罩:以像素級 Alpha 通道建立從不透明到透明的水平漸變效果。
  2. GIF 動畫播放:解析多幀 GIF,在背景執行緒按幀延遲時間循環繪製。

特效一:Alpha 漸層遮罩

核心邏輯

ImageData imageData = new ImageData("C:/icons/eclipse.jpg");
byte[] alphaValues = new byte[imageData.height * imageData.width];
for (int j = 0; j < imageData.height; j++) {
    for (int i = 0; i < imageData.width; i++) {
        // 左側不透明 (255) → 右側全透明 (0)
        alphaValues[j * imageData.width + i] = (byte) (255 - 255 * i / imageData.width);
    }
}
imageData.alphaData = alphaValues;
final Image image = new Image(display, imageData);

alphaData 陣列長度必須等於 width × height,每個位元組對應一個像素的 Alpha 值(0=全透明,255=不透明)。此例建立線性水平漸變,左側完整顯示圖片,右側逐漸消失。

繪製與資源管理

Canvas canvas = new Canvas(shell, SWT.NULL);
canvas.addPaintListener(e -> e.gc.drawImage(image, 10, 10));

// 視窗關閉時釋放
shell.addShellListener(new ShellAdapter() {
    public void shellClosed(ShellEvent e) { image.dispose(); }
});

使用 Canvas 而非 Label 可自訂繪製邏輯;PaintListener 確保視窗重繪時正確渲染。

特效二:GIF 動畫播放

載入多幀資料

ImageLoader loader = new ImageLoader();
ImageData[] frames = loader.load("C:/icons/eclipse-ani.gif");
// frames[0] 為邏輯螢幕尺寸,後續幀包含 x/y/delayTime/disposalMethod
Image canvasImage = new Image(display, frames[0].width, frames[0].height);
GC gc = new GC(canvasImage);

ImageLoader.load 回傳陣列,frames[0] 為標頭資訊,實際幀從 frames[1] 開始(視 GIF 結構而定)。每幀包含:

  • x, y:相對邏輯螢幕的繪製位置
  • delayTime:顯示時間(單位:百分之一秒,需 ×10 轉毫秒)
  • disposalMethod:下一幀前如何處理當前幀(還原背景/保留/還原上一幀)

背景執行緒循環播放

Thread animThread = new Thread() {
    int frameIndex = 0;
    public void run() {
        while (!isInterrupted()) {
            frameIndex %= frames.length;
            ImageData frameData = frames[frameIndex];
            
            display.asyncExec(() -> {
                Image frame = new Image(display, frameData);
                gc.drawImage(frame, frameData.x, frameData.y);
                frame.dispose();
                canvas.redraw(); // 觸發 PaintEvent
            });
            
            try { Thread.sleep(frameData.delayTime * 10); }
            catch (InterruptedException e) { return; }
            
            frameIndex++;
        }
    }
};
animThread.start();

關鍵點:

  • 所有 UI 操作(建立 Image、GC 繪製、redraw)必須在 UI 執行緒,故使用 display.asyncExec。
  • 每幀建立臨時 Image 繪製後立即 dispose(),避免記憶體洩漏。
  • 執行緒以 interrupt() 結束,配合 ShellListener.shellClosed 確保資源釋放。

畫布繪製邏輯

canvas.addPaintListener(e -> e.gc.drawImage(canvasImage, 0, 0));

動畫執行緒持續更新 canvasImage 內容,PaintListener 僅負責將最新畫面繪製到螢幕。

完整資源釋放模式

shell.addShellListener(new ShellAdapter() {
    public void shellClosed(ShellEvent e) {
        animThread.interrupt();
        gc.dispose();
        canvasImage.dispose();
        // 釋放所有幀 Image(若有預載)
    }
});

效能與優化建議

  1. 預載所有幀: 若動畫幀數少、尺寸小,可啟動時一次建立所有 Image 物件,播放時直接 gc.drawImage(preloadedImages[i], ...),省去重複建構開銷。
  2. 處理 Disposal Method: 完整播放器需依 disposalMethod 決定是否清除畫布或還原上一幀,本範例為簡化直接覆蓋繪製。
  3. 高 DPI 支援: 在高解析度螢幕上,ImageData 像素尺寸與邏輯座標可能不符,建議使用 ImageData.scaledTo 或啟用 SWT 自動縮放。

總結

Alpha 通道操作與多幀動畫是 SWT 圖形程式設計的基礎技能。掌握 ImageData.alphaData、ImageLoader、GC 雙緩衝繪製、asyncExec 執行緒協作與資源釋放模式,即可實作豐富的視覺效果,為桌面應用增添專業質感。

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