zoukankan      html  css  js  c++  java
  • MFC加载PNG图片并实现双缓冲

    因为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;
    			}
    		}
    	}
    }
    

      

  • 相关阅读:
    Java/IO流
    Java实现IO通信(服务器篇)
    利用哈夫曼二叉树实现文件的压缩
    关于字符串构建,连接,查找
    线程小球
    准备造一个轮子,关于图片浏览器的
    IOS之循环引用
    ARC
    构造方法与快速创建对象
    autorelease
  • 原文地址:https://www.cnblogs.com/shaellancelot/p/5026710.html
Copyright © 2011-2022 走看看