类CImage,头文件atlimage.h
1.显示背景透明的PNG图片
CImage m_Image;
m_Image.Load(图片路径);//装载图片
for(int i = 0; i < m_Image.GetWidth(); i++)
{
for(int j = 0; j < m_Image.GetHeight(); j++)
{
unsigned char* pucColor = reinterpret_cast<unsigned char *>(m_Image.GetPixelAddress(i , j));
pucColor[0] = pucColor[0] * pucColor[3] / 255;
pucColor[1] = pucColor[1] * pucColor[3] / 255;
pucColor[2] = pucColor[2] * pucColor[3] / 255;
}
}
m_Image.Draw(...)显示图片
BOOL CImage::Draw( HDC hDestDC, int xDest, int yDest, int nDestWidth,
int nDestHeight, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight )
2.显示整体半透明PNG图片
BOOL CImage::AlphaBlend( HDC hDestDC, int xDest, int yDest,
int nDestWidth, int nDestHeight, int xSrc, int ySrc, int nSrcWidth,
int nSrcHeight, BYTE bSrcAlpha, BYTE bBlendOp )
bSrcAlpha=255表示图片整体不透明
bSrcAlpha=0表示整体透明
备注:
typedef struct _BLENDFUNCTION {
BYTE BlendOp;
BYTE BlendFlags;
BYTE SourceConstantAlpha;
BYTE AlphaFormat;
}BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;
BlendOp:为AC_SRC_OVER
BlendFlags:为保留项,为0
SourceConstantAlpha:为图片整体的不透明度,如果要使用图片像素自身的Alpha值,则要将这个参数设置为255
AlphaFormat:如果使用SourceConstantAlpha作为描画图片的整体不透明度,则为设置为0,如果使用图片像素自身的Alpha值,则设置为AC_SRC_ALPHA.将AlphaFormat设置为AC_SRC_ALPHA.MSDN对这种情况下颜色混合的计算方法作了描述,如下:
Dst.Red = Src.Red + (1 - Src.Alpha) * Dst.Red
Dst.Green = Src.Green + (1 - Src.Alpha) * Dst.Green
Dst.Blue = Src.Blue + (1 - Src.Alpha) * Dst.Blue
Src是指我们要描画的图片,Dst是指目标DC的上下文,Src.Alpha应该不是像素的Alpha值,而应该是Alpha/255;按照这个公式,我们可以举个例子计算一下:Src上一个像素为RGB(255, 255, 255),Alpha值为0,与之混合的Dst上相应像素为RGB(128, 128, 128),混合后得出的结果为:
R = 255 + (1 - 0 / 255) * 128;
G = 255 + (1 - 0 / 255) * 128;
B = 255 + (1 - 0 / 255) * 128;
计算结果大于255,函数内部自动将其设置为255,最后为RGB(255, 255, 255),仍然为白色.而当Src中像素的颜色为RGB(0, 0, 0),则结果为Dst的颜色RGB(128, 128, 128),实现了透明效果.按照这个公式计算,很多颜色的半透明或透明效果都无法实现.
参考MSDN上在SourceConstantAlpha不等于255时的混合计算公式,我们可以将公式修改为
view plaincopy to clipboardprint?
Dst.Red = Src.Red * Src.Alpha + (1 - Src.Alpha) * Dst.Red
Dst.Green = Src.Green * Src.Alpha + (1 - Src.Alpha) * Dst.Green
Dst.Blue = Src.Blue * Src.Alpha + (1 - Src.Alpha) * Dst.Blue
源文档 <http://blog.sina.com.cn/s/blog_510a3ce00100gd3v.html>
PNG图片的透明背景总是一片白色,后来才发现这其实是微软GDI+的设计问题,PNG图片是ARGB,使用GDI+载入图片的时候,GDI+会默认已经进行了预剩运算(PARGB),即每象素的实际值是已经和ALPHA值按比例相乘的结果,实际上它根本就没有做预乘,在使用透明图片的象素ALPHA通道的时候,CImage内部正是调用的AlphaBlend,没有预乘的图当作预乘的图片处理的结果就是这相当于一张和纯白背景进行了预剩,所以图象总是出现白色背景。
最后的解决方法,写一个小程序对PNG图片每个象素进行预乘运算,然后保存成PNG图片,实际效果良好。
I overwrote CImage::Load() and now everything works fine:
HRESULT CImg::Load(LPCTSTR pszFileName, bool bPreMultiply)
{
HRESULT retRes = CImage::Load(pszFileName);
if(!IsNull() && bPreMultiply)
{
unsigned char * pCol = 0;
long lW = GetWidth();
long lH = GetHeight();
for(long ixy = 0; ixy < lH; ixy ++)
{
for(long ixx = 0; ixx < lW; ixx ++)
{
pCol = (unsigned char *)GetPixelAddress(ixx,ixy);
unsigned char alpha = pCol[3];
if(alpha < 255)
{
pCol[0] = ((pCol[0] * alpha) + 127) / 255;
pCol[1] = ((pCol[1] * alpha) + 127) / 255;
pCol[2] = ((pCol[2] * alpha) + 127) / 255;
}
}
}
}
return retRes;
}
PS:最后发现有一些png图的透明色可以被正常处理,现在怀疑是这些图片的导出方式不对导致。
源文档 <http://blog.csdn.net/mergerly/archive/2009/10/21/4710676.aspx>
分享到:
相关推荐
位图背景色设置为透明色,主界面加载一张图片之后,再次加载的图片在其上有底色,需要改变底色为透明的,可以看到背景色。
本程序实现了jpg图片、png图片、24位/32位位图转256色灰度位图图,使用了MFC框架,并且提供了保存位图的功能
默认编译环境VS2019+MFC RichEdit控件显示BMP图片 代码示例: //在RichEdit中图文混排显示资源中位图 void CRichEditTestDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 ..... } //在Rich...
http://www.vckbase.com/index.php/wv/206.html,这篇文章的源码,试了一下,美中不足是背景位图必须放在源程序文件夹下或者exe的同一文件夹下。所附教程的源码中没有位图,本资源中含有该位图
资源中是一个vs2008sp1 IDE中VC++ MFC 图片控件(Picture Control)显示资源位图(BMP)、文件位图(BMP)、其它格式文件图片(JPG\PNG\BMP)的实例,可供参考。
该工程为VS2010工程,里面有3类自绘按钮,其中利用PNG图片来简单实现了不规则按钮。
资源中是一个vs2008sp1 IDE中VC++ MFC 图片控件(Picture Control)显示资源位图(BMP)、文件位图(BMP)、其它格式文件图片(JPG\PNG\BMP)的实例,可供参考。
管理信息系统, 带文件数据库(mdb) 带背景贴图(位图非PNG)
用MFC实现的自绘按钮(该版本使用的BMP位图讲解),后续会上传PNG等格式的自绘方式(其实基本一样,只是图片资源的加载不一样)。 【含有详细注释】,有不明白的可以问我。
文字显示为Edit,使用重载,使用了位图背景减小透明带来的难以看清楚的不良效果,突出文字。在ColorCtrl中修改了文字颜色,目的同上。 2、界面色彩提供右击变幻,提供6种颜色更换。Edit中提供双击修改,右击保存,...
基于cximage实现的图片格式和位深度转换,基于cximage实现的图片格式和位深度转换
功能极为强大,与Windows、MFC支持极好,支持图像的多种操作(线性滤波、中值滤波、直方图操作、旋 转缩放、区域选取、阈值处理、膨胀腐蚀、alpha混合等等),支持从文件、内存或者win32api定义的位图图像格式中读取...
CImage是MFC和ATL共享的新类,它能从外部磁盘中调入一个JPEG、GIF、BMP和PNG格式的图像文件加以显示,而且这些文件格式可以相互转换。例如通过简单的几句,就可以实现CImage类和CBitmap类实例的:
6.5.2 改变图像的透明度 245 6.5.3 将图像转换为灰度图 249 6.5.4 改变图像的亮度 251 6.5.5 改变图像的对比度 253 6.6 本章实例:播放GIF动画 255 6.6.1 播放原理分析 255 6.6.2 处理过程 256 6.6.3 具体实现 257 ...
2014/10/11 16:12 13,340 C++模板类-classTest.rar 2014/11/10 21:55 179,424 CDib-位图操作类.rar 2007/12/06 13:16 2,678 CInifile.rar...2009/09/02 09:16 2,026 透明位图.rar 2009/07/03 13:10 47,141 透明窗体.rar
CImage类是ATL/MFC 共享类,提供增强的位图支持,包括能够加载和保存 JPEG、GIF、BMP 和可移植网络图形格式 (PNG) 的图像。提供了汾湖的从磁盘文件加载图像,图像位操作,图像保存等成员函数。本文件包包含这些使用...
本文主要介绍了VC编程控件类HTControl的CHTGDIManager GDI资源管理类用法,MFC提供的CBitmap类的LoadBitmap接口只能从EXE内部获取位图,但是很多情况下需要从EXE外部获取,CHTGDIManager类提供了从EXE外部获取位图的...
一般了解VC++的朋友都知道,VC++ 按钮控件CHTButton隶属HTControl控件组,直接由WIN32 API实现,你可以在SDK,MFC,wxWidget等环境下使用它。支持生成各种类型的按钮,比如:普通按钮,PNG透明按钮,复选框按钮,...
直接由WIN32 API实现。你可以在SDK,MFC,wxWidget等等方式下使用它。控制中包括一个垂直的控制杆控件,使用方式和水平的完全相同。窗体必须动态创建,具体代码段如下: m_HTSliderR.Create(130, 500, 400, 14, m_...