因為PNG包含Alpha通道,所以不同於BITMAP,在MFC中使用CImage類對其進行處理,通常使用load和draw成員函數。
所以標題的論述可以進一步解釋為,使用CImage實現雙緩沖。
通常的雙緩沖方法為(首先將消息函數afx_msg BOOL OnEraseBkgnd(CDC* pDC)的函數體改為return TRUE):
CDC memDC; CBitmap bmp; bmp.CreateCompatibleBitmap(pDC,WINDOW_WIDTH,WINDOW_HEIGHT); memDC.CreateCompatibleDC(pDC); memDC.SelectObject(&bmp); // 繪圖代碼 bmp.DeleteObject(); memDC.DeleteDC();
CImage可以通過Load成員函數加載圖片,然后通過Draw成員函數將圖片繪制到DC上。
Draw成員函數的原型為Bool Draw(HDC hDestDC, ...),它也需要獲取指定DC,但是如果將圖片一張一張繪制到DC上的話,就會產生閃爍。
因為雙緩沖的思想就是--將圖先繪制好,然后統一拷貝過去。
所以,解決方案就是將所有的圖片都貼在同一個CImage對象上,然后統一再調用Draw成員函數繪制到DC上(如果除了圖片還有其他繪制操作的話,此處DC應為memDC)。以下函數,是將圖片全部先繪制到一張圖片上:
void CRepairClientDlg::ShowImg(CImage &image, int x, int y) { image.Draw(m_cScreen.GetDC(), x, y);// m_cSreen為一個CImage對象 m_cScreen.ReleaseDC(); }
另:加載透明圖片的函數如下:
void CRepairClientDlg::LoadImg(CImage &image, CString &strPath) { image.Load(strPath); if (image.IsNull()) { MessageBox(_T("圖片未加載成功!")); return; } // 判斷是否需要透明顯示,並做相應處理 if (image.GetBPP() == 32) { for (int i = 0; i < image.GetWidth(); ++i) { for (int j = 0; j < image.GetHeight(); ++j) { byte *pByte = (byte *)image.GetPixelAddress(i, j); pByte[0] = pByte[0] * pByte[3] / 255; pByte[1] = pByte[1] * pByte[3] / 255; pByte[2] = pByte[2] * pByte[3] / 255; } } } }