工作需要又得使用MFC编调试软件。
需要载入一张公司的logo,透明PNG图片。
查了很多资料都没显示,也不想使用其他类。最后用Cimage基本解决。
1.在对话框类的头文件中定义:
- CImage img;
2.在Onpaint消息响应函数中载入图片并显示图片。
- if (IsIconic())
- {
- CPaintDC dc(this); // 用于绘制的设备上下文
- SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
- // 使图标在工作区矩形中居中
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
- // 绘制图标
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CPaintDC dc(this);
- if(!img.IsNull()) img.Destroy();
- img.Load(_T("12.png")); //load载入,否则不显示
- TransparentPNG(&img); //调用透明化处理函数
- if(!img.IsNull()) img.Draw(dc.m_hDC, 80, 20); //以左上角为原点,按原始大小,在(80,20)处贴图
- CDialogEx::OnPaint();
- }
3.直接载入将会的到衣服背景色不透明的图片,很傻单也简单实用的办法,将png图像的没像素的RGB值惊进行处理,消除白色背景。
- void TransparentPNG(CImage *png)
- {
- for(int i = 0; i <png->GetWidth(); i++) <span style="white-space:pre;"> </span>//遍历像素处理
- {
- for(int j = 0; j <png->GetHeight(); j++)
- {
- unsigned char* pucColor = reinterpret_cast<unsigned char*>(png->GetPixelAddress(i , j));
- pucColor[0] = pucColor[0] *pucColor[3] / 255;
- pucColor[1] = pucColor[1] *pucColor[3] / 255;
- pucColor[2] = pucColor[2] *pucColor[3] / 255;
- }
- }
- }
至此就简单的实现了。
方式二:
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)
- if (IsIconic())
- {
- CPaintDC dc(this); // 用于绘制的设备上下文
- SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
- // 使图标在工作区矩形中居中
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
- // 绘制图标
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CPaintDC dc(this);
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(); }