依然没有搞懂TransparentBlt的原理

zrdongjiao 2013-12-27 09:58:20


文章摘自: http://www.vckbase.com/index.php/wv/358

问题1:
为什么要对hImageDC 进行 setbkcolor ? ,仔细看,football.bmp本身就是
蓝色透明的。还有,setbkcolor是否真正管用,看msdn,其效果是体现在bitblt或者stretchblt的时候。

问题2:
针对图2的问题, 为什么要 对hImageDc进行settextcolor ?
这个函数是对字体设置颜色, 可是文章里说的不是“字体”,而是
前景,看代码:
settextcolor(hImageDC, RGB(255,255,255));

这句代码会是什么效果呢?

大家都看到了,这图片中哪里来的字体? football.bmp里没有字体啊。
...全文
484 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
bsnry 2013-12-27
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
在 dos 是 文字 分为 前景色 和 背景色。
在这里 settextcolor(hImageDC, RGB(255,255,255)); 就是 前景 色


引用 楼主 zrdongjiao 的回复:


文章摘自: http://www.vckbase.com/index.php/wv/358

问题1:
为什么要对hImageDC 进行 setbkcolor ? ,仔细看,football.bmp本身就是
蓝色透明的。还有,setbkcolor是否真正管用,看msdn,其效果是体现在bitblt或者stretchblt的时候。

问题2:
针对图2的问题, 为什么要 对hImageDc进行settextcolor ?
这个函数是对字体设置颜色, 可是文章里说的不是“字体”,而是
前景,看代码:
settextcolor(hImageDC, RGB(255,255,255));

这句代码会是什么效果呢?

大家都看到了,这图片中哪里来的字体? football.bmp里没有字体啊。


颜色就是前景色,背景色是背景色,

看图:


schlafenhamster 2013-12-27
  • 打赏
  • 举报
回复
在 dos 是 文字 分为 前景色 和 背景色。 在这里 settextcolor(hImageDC, RGB(255,255,255)); 就是 前景 色
MoreWindows 2013-12-27
  • 打赏
  • 举报
回复
问题都已经解决了呀~呵呵,那就推荐2篇类似的文章供楼主参考吧。 《Windows界面编程第三篇 异形窗体 普通版》 http://blog.csdn.net/morewindows/article/details/8451633 《Windows界面编程第四篇 异形窗体 高富帅版》 http://blog.csdn.net/morewindows/article/details/8451638
zrdongjiao 2013-12-27
  • 打赏
  • 举报
回复
引用 6 楼 worldy 的回复:
1,代码中没有对单色位图使用settextcolor 2,实在没 看明白你说的什么意思, 请仔细理解我在每部分代码中的注释
谢谢你的解答, 我发现以前有人问过这个问题了。 如果有需要的朋友,可以参考帖子: http://bbs.csdn.net/topics/350042641 这里有人问过类似问题。 答案在11楼。 windows非开源,这种东西只能猜测。 再次感谢你的回答。
worldy 2013-12-27
  • 打赏
  • 举报
回复
1,代码中没有对单色位图使用settextcolor 2,实在没 看明白你说的什么意思, 请仔细理解我在每部分代码中的注释
zrdongjiao 2013-12-27
  • 打赏
  • 举报
回复
引用 4 楼 worldy 的回复:
花了大半天时间研究,终于基本弄明白了 ms的文档说的不全,那两个函数没有说明对ROP操作的影响!
void TransparentBlt2(	HDC hdcDest,      // 目标DC 
							int nXOriginDest,   // 目标X偏移 
							int nYOriginDest,   // 目标Y偏移 
							int nWidthDest,     // 目标宽度 
							int nHeightDest,    // 目标高度 
							HDC hdcSrc,         // 源DC 
							int nXOriginSrc,    // 源X起点 
							int nYOriginSrc,    // 源Y起点 
							int nWidthSrc,      // 源宽度 
							int nHeightSrc,     // 源高度 
							UINT crTransparent  // 透明色,COLORREF类型 
							) 
	{ 
		HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest); // 创建兼容位图 
		HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);          // 创建单色掩码位图 
		HDC     hImageDC = CreateCompatibleDC(hdcDest); 
		HDC     hMaskDC = CreateCompatibleDC(hdcDest); 

		hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP); 
		hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP); 
		// 将源DC中的位图拷贝到临时DC中 
		if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc) 
			BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY); 
		else
			StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest,  
			hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY); 

		// 设置透明色 
		SetBkColor(hImageDC, crTransparent); 

		// 生成透明区域为白色,其它区域为黑色的掩码位图 
		//推测:发生彩色转单色,如果是背景色转换为1,非背景色,转换为0
		BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY); 

		// 生成透明区域为黑色,其它区域保持不变的位图 
		SetBkColor(hImageDC, RGB(0,0,0) ); 
		SetTextColor(hImageDC,RGB(255,255,255)); 
		//SetBkColor(hMaskDC, crTransparent+1); //对效果没有影响。说明hMaskDC的背景色对后续的操作没有影响
		//推测:
		//此处首先进行单色到彩色的转换,然后将转换的结果执行与操作
		//1,掩码图的1转换为指定的背景色(此处为黑),掩码图的0转换为前景(此处为白),发生了黑白颠倒产生的中间图片Tmp
		//2,Tmp和hImageDC进行与操作,即原来球的透明色与0与,全部转为0,球部分和1与,保留原值
		BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND); 

		// 透明部分保持屏幕不变,其它部分变成黑色 
		SetBkColor(hdcDest,RGB(255,255,255)); 
		SetTextColor(hdcDest,RGB(0,0,0)); 
		//同上操作,只是目标转换到背景DC
		//掩码图的背景(1的位置),转换为指定的背景色(此处为白色),掩码图的0位置转换为前景色(此处为黑色)

	}
1. settextcolor对 “单色图” 是不管用的 2.还有,对目标 图片进行 settextcolor 作用是“球体”的前景色改变了。 对目标图片进行 setbkcolor会导致球体的背景色改变。 但是 贴图后, 并不会呈现出 你所设置的颜色。
worldy 2013-12-27
  • 打赏
  • 举报
回复
花了大半天时间研究,终于基本弄明白了 ms的文档说的不全,那两个函数没有说明对ROP操作的影响!
void TransparentBlt2(	HDC hdcDest,      // 目标DC 
							int nXOriginDest,   // 目标X偏移 
							int nYOriginDest,   // 目标Y偏移 
							int nWidthDest,     // 目标宽度 
							int nHeightDest,    // 目标高度 
							HDC hdcSrc,         // 源DC 
							int nXOriginSrc,    // 源X起点 
							int nYOriginSrc,    // 源Y起点 
							int nWidthSrc,      // 源宽度 
							int nHeightSrc,     // 源高度 
							UINT crTransparent  // 透明色,COLORREF类型 
							) 
	{ 
		HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest); // 创建兼容位图 
		HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);          // 创建单色掩码位图 
		HDC     hImageDC = CreateCompatibleDC(hdcDest); 
		HDC     hMaskDC = CreateCompatibleDC(hdcDest); 

		hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP); 
		hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP); 
		// 将源DC中的位图拷贝到临时DC中 
		if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc) 
			BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY); 
		else
			StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest,  
			hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY); 

		// 设置透明色 
		SetBkColor(hImageDC, crTransparent); 

		// 生成透明区域为白色,其它区域为黑色的掩码位图 
		//推测:发生彩色转单色,如果是背景色转换为1,非背景色,转换为0
		BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY); 

		// 生成透明区域为黑色,其它区域保持不变的位图 
		SetBkColor(hImageDC, RGB(0,0,0) ); 
		SetTextColor(hImageDC,RGB(255,255,255)); 
		//SetBkColor(hMaskDC, crTransparent+1); //对效果没有影响。说明hMaskDC的背景色对后续的操作没有影响
		//推测:
		//此处首先进行单色到彩色的转换,然后将转换的结果执行与操作
		//1,掩码图的1转换为指定的背景色(此处为黑),掩码图的0转换为前景(此处为白),发生了黑白颠倒产生的中间图片Tmp
		//2,Tmp和hImageDC进行与操作,即原来球的透明色与0与,全部转为0,球部分和1与,保留原值
		BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND); 

		// 透明部分保持屏幕不变,其它部分变成黑色 
		SetBkColor(hdcDest,RGB(255,255,255)); 
		SetTextColor(hdcDest,RGB(0,0,0)); 
		//同上操作,只是目标转换到背景DC
		//掩码图的背景(1的位置),转换为指定的背景色(此处为白色),掩码图的0位置转换为前景色(此处为黑色)
		//然后和背景图与操作,透明色的位置和1与,保留源背景,球的位置和0与,被转换为黑色(背景图被挖出一个黑色的洞)
		BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND); 

		// "或"运算,生成最终效果 
		BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT); 
		// 清理、恢复     
		SelectObject(hImageDC, hOldImageBMP); 
		DeleteDC(hImageDC); 
		SelectObject(hMaskDC, hOldMaskBMP); 
		DeleteDC(hMaskDC); 
		DeleteObject(hImageBMP); 
		DeleteObject(hMaskBMP); 
	}
zrdongjiao 2013-12-27
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
在 dos 是 文字 分为 前景色 和 背景色。 在这里 settextcolor(hImageDC, RGB(255,255,255)); 就是 前景 色
看源码 hImageDC 是临时dc, hImageBmp是兼容位图, hdcDest是目的dc, hMaskDC是mask void TransparentBlt2( HDC hdcDest, // 目标DC int nXOriginDest, // 目标X偏移 int nYOriginDest, // 目标Y偏移 int nWidthDest, // 目标宽度 int nHeightDest, // 目标高度 HDC hdcSrc, // 源DC int nXOriginSrc, // 源X起点 int nYOriginSrc, // 源Y起点 int nWidthSrc, // 源宽度 int nHeightSrc, // 源高度 UINT crTransparent // 透明色,COLORREF类型 ) { HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest); // 创建兼容位图 HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 创建单色掩码位图 HDC hImageDC = CreateCompatibleDC(hdcDest); HDC hMaskDC = CreateCompatibleDC(hdcDest); hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP); hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP); // 将源DC中的位图拷贝到临时DC中 if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc) BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY); else StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY); // 设置透明色 SetBkColor(hImageDC, crTransparent); //hImage这个临时的,已经成为背景为透明,前景为球体的 了 // 生成透明区域为白色,其它区域为黑色的掩码位图 BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY); //问题1:这里hMaskDC为什么会变成 背景为白色,前景为黑色? //这里是srccopy啊。 是拷贝.
	// 生成透明区域为黑色,其它区域保持不变的位图
	SetBkColor(hImageDC, RGB(0,0,0));
	SetTextColor(hImageDC, RGB(255,255,255));
	BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

	// 透明部分保持屏幕不变,其它部分变成黑色
	SetBkColor(hdcDest,RGB(0xff,0xff,0xff));
	SetTextColor(hdcDest,RGB(0,0,0));
	BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
	
	// "或"运算,生成最终效果
	BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);
	
	SelectObject(hImageDC, hOldImageBMP);
	DeleteDC(hImageDC);
	SelectObject(hMaskDC, hOldMaskBMP);
	DeleteDC(hMaskDC);
	DeleteObject(hImageBMP);
	DeleteObject(hMaskBMP);
	
}

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧