MFC 显示透明png图片

工作需要又得使用MFC编调试软件。

需要载入一张公司的logo,透明PNG图片。

查了很多资料都没显示,也不想使用其他类。最后用Cimage基本解决。

1.在对话框类的头文件中定义:

[cpp]  view plain  copy
  1. CImage img;  

2.在Onpaint消息响应函数中载入图片并显示图片。

[cpp]  view plain  copy
  1. if (IsIconic())  
  2. {  
  3.         CPaintDC dc(this); // 用于绘制的设备上下文  
  4.   
  5.         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);  
  6.   
  7.         // 使图标在工作区矩形中居中  
  8.         int cxIcon = GetSystemMetrics(SM_CXICON);  
  9.         int cyIcon = GetSystemMetrics(SM_CYICON);  
  10.         CRect rect;  
  11.         GetClientRect(&rect);  
  12.         int x = (rect.Width() - cxIcon + 1) / 2;  
  13.         int y = (rect.Height() - cyIcon + 1) / 2;  
  14.   
  15.   
  16.         // 绘制图标  
  17.         dc.DrawIcon(x, y, m_hIcon);  
  18.     }  
  19.     else  
  20.     {  
  21.             CPaintDC dc(this);          
  22.             if(!img.IsNull()) img.Destroy();  
  23.               img.Load(_T("12.png"));                           //load载入,否则不显示  
  24.             TransparentPNG(&img);                               //调用透明化处理函数  
  25.             if(!img.IsNull()) img.Draw(dc.m_hDC, 80, 20);      //以左上角为原点,按原始大小,在(80,20)处贴图  
  26.   
  27.             CDialogEx::OnPaint();  
  28.     }  


3.直接载入将会的到衣服背景色不透明的图片,很傻单也简单实用的办法,将png图像的没像素的RGB值惊进行处理,消除白色背景。

[cpp]  view plain  copy
  1. void TransparentPNG(CImage *png)    
  2. {    
  3.     for(int i = 0; i GetWidth(); i++)  "white-space:pre;">              //遍历像素处理  
  4.     {    
  5.         for(int j = 0; j GetHeight(); j++)    
  6.         {    
  7.             unsigned char* pucColor = reinterpret_castchar*>(png->GetPixelAddress(i , j));    
  8.             pucColor[0] = pucColor[0] *pucColor[3] / 255;    
  9.             pucColor[1] = pucColor[1] *pucColor[3] / 255;    
  10.             pucColor[2] = pucColor[2] *pucColor[3] / 255;    
  11.         }    
  12.     }    
  13. }  

至此就简单的实现了。

方式二:

AlphaBlend是Window自带的GDI函数,在作GUI的时候为了达到更漂亮的效果我们常常用它.

 

BLENDFUNCTION是AlphaBlend用控制透明效果的重要参数.

 

定义如下:

 

typedef struct _BLENDFUNCTION {
  BYTE     BlendOp;
  BYTE     BlendFlags;
  BYTE     SourceConstantAlpha;
  BYTE     AlphaFormat;
}BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;

 

BlendOp: 这个参数必须也只能为AC_SRC_OVER(0x00),意思就是把源图片覆盖到目标之上.

BlendFlags: 必须为0

SourceConstantAlpha: 简写为SCA,指定源图片的透明度,这个值是会和源图片的Alpha通道值合并计算的.

AlphaFormat: 可以填两种,一种是0x00,一种是AC_SRC_ALPHA(0x01).填0的话,AlphaBlend据说就和BitBlt一样了,我没有试验过~填1的话,源DC必须是32位的DC不然的话,AlphaBlend会返回参数错误.

 

计算公式(当SCA不是0xFF时):

      输出像素(R,G,B,A) = 源像素(R,G,B,A) * SCA / 0xFF + 目标像素(R,G,B,A) * (1.0 - SCA / 0xFF)

当SCA是0xFF时,计算公式

      输出像素(R,G,B,A) = 源像素(R,G,B,A) + 目标像素(R,G,B,A) * (1.0 - 源像素(A) / 0xFF)

混合计算公式

       输出像素(R,G,B) = 源像素(R,G,B) * SCA / 0xFF + 目标像素(R,G,B) * (1.0 - 源像素(A) / 0xFF * SCA / 0xFF)


  1. if (IsIconic())  
  2. {  
  3.         CPaintDC dc(this); // 用于绘制的设备上下文  
  4.   
  5.         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);  
  6.   
  7.         // 使图标在工作区矩形中居中  
  8.         int cxIcon = GetSystemMetrics(SM_CXICON);  
  9.         int cyIcon = GetSystemMetrics(SM_CYICON);  
  10.         CRect rect;  
  11.         GetClientRect(&rect);  
  12.         int x = (rect.Width() - cxIcon + 1) / 2;  
  13.         int y = (rect.Height() - cyIcon + 1) / 2;  
  14.   
  15.   
  16.         // 绘制图标  
  17.         dc.DrawIcon(x, y, m_hIcon);  
  18.     }  
  19.     else  
  20.     {  
  21.                            CPaintDC dc(this);
if (!img.IsNull()) img.Destroy();
img.Load(_T("logo.png"));                           //load载入,否则不显示  
HDC hMemDC;
HBITMAP bmpMem;
bmpMem = CreateCompatibleBitmap(dc.m_hDC, 413, 69);
hMemDC = CreateCompatibleDC(dc.m_hDC);
HGDIOBJ hOldObj =  ::SelectObject(hMemDC, bmpMem);


BLENDFUNCTION bindfun;


//设置AlphaBind的最后一个参数  
bindfun.BlendOp = AC_SRC_OVER;
bindfun.BlendFlags = 0;
bindfun.SourceConstantAlpha = 255;
bindfun.AlphaFormat = AC_SRC_ALPHA;  // AC_SRC_ALPHA


//img.AlphaBlend(hMemDC, 0, 0, 413, 69, 0, 0, 413, 69, bindfun);


AlphaBlend(hMemDC, 0, 0, 413, 69, img.GetDC(), 0, 0, 413, 69, bindfun);
::TransparentBlt(dc.m_hDC, 80, 20, 413, 69, hMemDC, 0, 0, 412, 68, RGB(0, 0, 0));                CDialogEx::OnPaint();       }  

你可能感兴趣的:(MFC 显示透明png图片)