文章出處

本文章由楊芹勍原創,如需轉摘請注明出處。謝謝!

所謂“雙緩沖”,指的是在繪圖時并不是直接繪到屏幕上,而是在內存中開辟一個緩沖區,在這個緩沖區里完成所有的繪圖后,直接將其“粘貼”到屏幕上。采用雙緩沖技術,由于繪圖操作大部分在內存中完成,所以繪圖速度沒有太大的制約;此外,當進行復雜的繪圖操作時,使用雙緩沖技術可以有效的防止畫面的閃爍。

一、雙緩存技術在J2ME中的實現

在J2ME中,實現雙緩存繪制圖形可以通過以下步驟實現:

  1. 首先創建一個類成員變量Image對象,此Image對象的圖像尺寸為屏幕尺寸大小。
    如:如果屏幕大小為240*320,則使用以下代碼創建:

    private Image img;
    img = Image.createImage(240, 320);

  2. 創建一個類成員變量Graphics對象,此Graphics對象指向img的Graphics對象:

    private Graphics g;
    g = img.getGraphics();

  3. 以上img對象即為內存中的緩沖區,可以使用任何方法在類成員g上繪制任意的圖像,而不用在canvas的repaint事件中處理復雜的繪制過程。
  4. 在canvas的repaint方法,將緩沖區圖像繪制在屏幕的gc上:

    protected void paint(Graphics g) {
    g.drawImage(img, 0, 0, Graphics.LEFT | Graphics.TOP);
    }

以上就在J2ME中完成了簡單的的雙緩存的實現。

二、雙緩存技術在Symbian中的實現

在Symbian中實現雙緩沖技術有兩種方法,我們先從簡單的方法入手:

  1. 第一種方法的實現更貼近于在J2ME中的實現。在此方法中,也得先在內存中建立一個位圖緩沖區對象,然后再獲取位圖對象的設備上下文 dc(Device Context)(類似于J2ME中的Graphics),程序可以在任意的地方對內存緩沖位圖的dc繪制圖形。在Draw事件(相當于J2ME的 paint事件)內,將緩沖區位圖直接繪制在設備的dc上。
    首先在頭文件中加入如下定義:

    CWsBitmap* iBufBmp;
    CFbsBitmapDevice* iBufDevice;
    CBitmapContext* iBufGc;

    1) iBufBmp為緩沖區位圖對象,為CWsBitmap類型。類CWsBitmap繼承自類CFbsBitmap,我們在此使用CWsBitmap的原因為因為它比較快,引入SDK中對CWsBitmap類的說明:

    This is a bitmap to which the window server already has a handle. Functions
    which take a window server bitmap are faster than equivalent functions which
    take a CFbsBitmap.

    2) iBufDevice為CFbsBitmapDevice類型的對象,CFbsBitmapDevice的官方解釋可以簡單的理解為管理文字和位圖的圖形設備:
    A graphics device to which a bitmap managed by the font and bitmap server can be drawn.

    3) iBufGc為CBitmapContext類型的對象,即位圖對象的設備上下文dc,獲取了iBufGc后,可以使用CBitmapContext中的方法對位圖進行繪制。

    關鍵部分代碼:

    /**
    * 初始化雙緩沖區
    */
    void CTestDoubleBufferAppView::InitDoubleBufferL()
    {
    iBufBmp = new(ELeave)CWsBitmap(CEikonEnv::Static()->WsSession());
    CleanupStack::PushL(iBufBmp);
    User::LeaveIfError(iBufBmp->Create(Rect().Size(), CEikonEnv::Static()->ScreenDevice()->DisplayMode()));

    iBufDevice = CFbsBitmapDevice::NewL(iBufBmp);
    CleanupStack::PushL(iBufDevice);
    User::LeaveIfError(iBufDevice->CreateBitmapContext(iBufGc));

    CleanupStack::Pop(2); // iDevice, iBufBmp
    }

    /**
    * 測試在緩沖區上繪制
    */
    void CTestDoubleBufferAppView::DoTestDraw()
    {
    iBufGc->Clear(Rect());

    // 在buffer里畫方塊,而不是在屏幕上
    for (int i=0; i<100; i+=2)
    {
    iBufGc->DrawRect(TRect(TPoint(i, i), TSize(50, 50)));
    }

    }

    /**
    * View的重繪事件
    */
    void CTestDoubleBufferAppView::Draw(const TRect& /*aRect*/) const
    {
    // 以下代碼忽略
    //    // Get the standard graphics context
    //    CWindowGc& gc = SystemGc();
    //
    //    // Gets the control's extent
    //    TRect drawRect(Rect());
    //
    //    // Clears the screen
    //    gc.Clear(drawRect);

    SystemGc().BitBlt(TPoint(0, 0), iBufBmp);

    }

    完整代碼下載

三、參考文獻

  1. Symbian OS:創建自定義控件

不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 AutoPoster 的頭像
    AutoPoster

    互聯網 - 大數據

    AutoPoster 發表在 痞客邦 留言(0) 人氣()