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

Java Applet 圖像顯示技術:從基礎載入到雙緩衝優化

     編輯:Java 相關知識

Java Applet 圖像處理基礎

Java Applet 常用於顯示儲存在 GIF 或 JPEG 格式檔案中的圖像。處理圖像時,需定義 java.awt.Image 物件,並使用 getImage() 方法將圖像檔案與 Image 物件關聯。為了提升顯示效能與流暢度,許多 Applet 採用**雙緩衝技術**:先將圖像完整載入記憶體,再一次性繪製到螢幕上,避免畫面閃爍與不連續顯示。

核心類別與方法

類別/方法用途
java.awt.Image圖像資料的抽象表示
Applet.getImage(URL, String)載入圖像:第一參數為基底 URL(通常用 getCodeBase()),第二參數為相對路徑檔名
Graphics.drawImage(Image, x, y, ImageObserver)繪製圖像:指定左上角座標 (x,y) 與觀察者(通常傳 this 或 null)
Component.createImage(w, h)建立離屏圖像(雙緩衝核心)
Image.getGraphics()取得離屏圖像的繪圖環境
imageUpdate(Image, flags, x, y, w, h)非同步載入回調:監控圖像載入進度,flags 含 ALL_BITS 表示完成

基本圖像顯示範例

import java.awt.*;
import java.applet.*;

public class ShowImage extends Applet {
    Image picture; // 成員變數持有圖像參考

    public void init() {
        // 載入圖像:getCodeBase() 返回 Applet 所在 URL 目錄
        picture = getImage(getCodeBase(), "Image.gif");
    }

    public void paint(Graphics g) {
        // 直接繪製:第四參數 this 註冊 imageUpdate 回調
        g.drawImage(picture, 0, 0, this);
    }
}

對應 HTML:

<HTML>
<TITLE>Show Image Applet</TITLE>
<APPLET CODE="ShowImage.class" WIDTH=600 HEIGHT=400>
</APPLET>
</HTML>

問題:drawImage() 非同步執行,會建立執行緒一邊載入一邊繪製,導致圖像逐漸顯示(撕裂、閃爍),體驗不佳。

雙緩衝技術實現

核心思路:離屏繪製 → 載入完成 → 一次性翻轉到螢幕。

import java.awt.*;
import java.applet.*;

public class BackgroundImage extends Applet {
    Image picture;           // 原始圖像
    Image offScreenImage;    // 離屏緩衝區
    Graphics offScreenGC;    // 離屏繪圖環境
    boolean imageLoaded = false; // 載入完成旗標

    public void init() {
        picture = getImage(getCodeBase(), "Image.gif");

        // 1. 建立離屏圖像(與 Applet 同尺寸)
        offScreenImage = createImage(size().width, size().height);
        // 2. 取得離屏繪圖環境
        offScreenGC = offScreenImage.getGraphics();
        // 3. 在離屏繪製圖像(觸發非同步載入,註冊 this 為觀察者)
        offScreenGC.drawImage(picture, 0, 0, this);
    }

    public void paint(Graphics g) {
        if (imageLoaded) {
            // 載入完成:直接繪製已就緒的離屏圖像,第四參數 null 避免再次觸發 imageUpdate
            g.drawImage(offScreenImage, 0, 0, null);
            showStatus("Done");
        } else {
            showStatus("Loading image...");
        }
    }

    // 非同步載入回調:由 drawImage 內部執行緒定期呼叫
    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
        if ((infoflags & ALLBITS) != 0) { // 圖像完全載入
            imageLoaded = true;
            repaint(); // 觸發 paint() 重繪
            return false; // 停止後續回調
        }
        return true; // 繼續監控
    }
}

關鍵流程解析

  1. init():建立離屏緩衝區(offScreenImage),在離屏環境(offScreenGC)繪製原始圖像。此時螢幕**無任何顯示**。
  2. drawImage() 內部機制:建立載入執行緒,定期呼叫 imageUpdate() 回報進度(infoflags)。
  3. imageUpdate():檢測 ALLBITS 標誌 → 設定 imageLoaded=true → 呼叫 repaint() → 返回 false 停止回調。
  4. paint():受 imageLoaded 控制。完成前顯示載入狀態;完成後繪製**離屏圖像**(而非原始 picture),第四參數傳 null 避免重複註冊觀察者。

效能與體驗提升

  • 消除閃爍:螢幕只見最終完整圖像,無中間態。
  • 流暢度:repaint() 觸發的 paint() 直接繪製記憶體圖像,極快。
  • 資源管理:離屏圖像在 Applet 生命週期內複用,避免重複建立。

現代替代方案提示

注意:Java Applet 技術已過時(JDK 9 標記棄用,JDK 11 移除),現代 Web 開發請使用:

  • HTML5 Canvas / WebGL:原生瀏覽器圖形渲染
  • JavaFX:豐富客戶端應用(可部署為 Web Start 或原生安裝)
  • Swing/AWT 桌面應用:同樣適用雙緩衝技術(BufferStrategy、RepaintManager)

雙緩衝原理在現代圖形程式設計中依然通用,理解其核心機制有助於解決各類渲染閃爍問題。

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