本文章由楊芹勍原創,如需轉摘請注明出處。謝謝!
所謂“雙緩沖”,指的是在繪圖時并不是直接繪到屏幕上,而是在內存中開辟一個緩沖區,在這個緩沖區里完成所有的繪圖后,直接將其“粘貼”到屏幕上。采用雙緩沖技術,由于繪圖操作大部分在內存中完成,所以繪圖速度沒有太大的制約;此外,當進行復雜的繪圖操作時,使用雙緩沖技術可以有效的防止畫面的閃爍。
一、雙緩存技術在J2ME中的實現
在J2ME中,實現雙緩存繪制圖形可以通過以下步驟實現:
- 首先創建一個類成員變量Image對象,此Image對象的圖像尺寸為屏幕尺寸大小。
如:如果屏幕大小為240*320,則使用以下代碼創建:private Image img;
img = Image.createImage(240, 320); - 創建一個類成員變量Graphics對象,此Graphics對象指向img的Graphics對象:
private Graphics g;
g = img.getGraphics(); - 以上img對象即為內存中的緩沖區,可以使用任何方法在類成員g上繪制任意的圖像,而不用在canvas的repaint事件中處理復雜的繪制過程。
- 在canvas的repaint方法,將緩沖區圖像繪制在屏幕的gc上:
protected void paint(Graphics g) {
g.drawImage(img, 0, 0, Graphics.LEFT | Graphics.TOP);
}
以上就在J2ME中完成了簡單的的雙緩存的實現。
二、雙緩存技術在Symbian中的實現
在Symbian中實現雙緩沖技術有兩種方法,我們先從簡單的方法入手:
- 第一種方法的實現更貼近于在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);
}
三、參考文獻
不含病毒。www.avast.com |
留言列表