bitblt函数 透明底图_手绘楼盘摆位图怎么画

bitblt函数 透明底图_手绘楼盘摆位图怎么画CDC::BitBlt函数,应用在GDI的绘图中,有时候我们需要显示的位图有一部分是透明的,例如在棋类游戏中,棋盘图片和棋子图片融合的时候,棋子边缘应该是透明。    在图1中,棋盘和棋子图片融合在一起,需要设置棋子图片边缘的“品红色”为透明。     1、BitBlt函数说明:        BOOLBitBlt(intx,int

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

       CDC::BitBlt函数,应用在GDI的绘图中,有时候我们需要显示的位图有一部分是透明的,例如在棋类游戏中,棋盘图片和棋子图片融合的时候,棋子边缘应该是透明。

       在图1中,棋盘和棋子图片融合在一起,需要设置棋子图片边缘的“品红色”为透明。bitblt函数 透明底图_手绘楼盘摆位图怎么画

BitBlt函数说明:              

                    

BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );

          
CSDN中关于bitblt函数的说明 :Copies a bitmap from the source device context to this current device context.   将源设备上下文中一个位图,拷贝到当前设备上下文中。其中x,y是当前设备上下文的绘图位置,nWidth和nHeight是位图大小,xSrc和ySrc是源设备上下文的位图位置。dwRop 是源位图和当前位图的运算方式,下面是其取值

BLACKNESS 用黑色填充目标矩形区域.

DSTINVERT 将目标矩形图象进行反相.

MERGECOPY 将源矩形图象与指定的图案刷(Pattern)进行布尔”与”运算.

MERGEPAINT 将源矩形图形经过反相后,与目标矩形图象进行布尔”或”运算.

NOTSRCCOPY 将源矩形图象经过反相后,复制到目标矩形上.

NOTSRCERASE 先将源矩形图象与目标矩形图象进行布尔”或”运算,然后再将得图象进行反相.

PATCOPY 将指定的图案刷复制到目标矩形上.

PATINVERT 将指定的图案刷与目标矩形图象进行布尔”异或”运算.

PATPAINT 先将源矩形图象进行反相,与指定的图案刷进行布尔”或”运算,

再与目标矩形图象进行布尔”或”运算

SRCAND 将源矩形图象与目标矩形图象进行布尔”与”运算.

SRCCOPY 将源矩形图象直接复制到目标矩形上.

SRCERASE 将目标矩形图象进行反相,再与源矩形图象进行布尔”与”运算.

SRCINVERT 将源矩形图象与目标矩形图象进行布尔”异或”运算.

SRCPAINT 将源矩形图象与目标矩形图象进行布尔”或”运算.

WHITENESS 用白色填充目标矩形区域.

  下面举例说明 位图的运算方式,两个位图按照对应像素 按位运算          例如像素(R1,G1,B1)和(R2,G2,B2)采用SRCAND “与”运算,则结果为(R1&R2,G1&G2,B1&B2)。

测试:建立MFC单文档,在资源中添加BITMAP资源IDB_BITMAP1,IDB_BITMAP2,在view类的OnDraw中,添加以下代码:

<span style="font-size:18px;">void CXXXXXXXXView::OnDraw(CDC* pDC)
{
	CceshiTransparentDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	//图片1
	CBitmap bitmap1;
	bitmap1.LoadBitmap(IDB_BITMAP1);
	CDC  dcMem1;
	dcMem1.CreateCompatibleDC(pDC);
	CBitmap *pOldBitmap1=dcMem1.SelectObject(&bitmap1);

	//获取图像尺寸
	BITMAP  bitmapInfo;
	bitmap1.GetBitmap(&bitmapInfo);
	
	//图片2
	CBitmap bitmap2;
	bitmap2.LoadBitmap(IDB_BITMAP2);
	CDC  dcMem2;
	dcMem2.CreateCompatibleDC(pDC);
	CBitmap *pOldBitmap2=dcMem2.SelectObject(&bitmap2);
	
	//两个位图取“与”
	pDC->BitBlt(100,100,bitmapInfo.bmWidth,bitmapInfo.bmHeight,&dcMem1,0,0,SRCCOPY);
	pDC->BitBlt(100,100,bitmapInfo.bmWidth,bitmapInfo.bmHeight,&dcMem2,0,0,SRCAND);
	 
	dcMem1.SelectObject(pOldBitmap1);
	dcMem2.SelectObject(pOldBitmap2);

	dcMem1.DeleteDC();
	dcMem2.DeleteDC();
}</span>

测试位图

bitblt函数 透明底图_手绘楼盘摆位图怎么画                                          bitblt函数 透明底图_手绘楼盘摆位图怎么画

结果:

bitblt函数 透明底图_手绘楼盘摆位图怎么画

从结果图可以看出,位图操作是逐pixel逐bit进行运算的。

 单色位图与彩色位图的相互转化


CSDN中关于bitblt函数还有以下说明,

If destination, source, and pattern bitmaps do not have the same color format, theBitBlt function converts the source and pattern bitmaps to match the destination. The foreground and background colors of the destination bitmap are used in the conversion.

When the BitBlt function converts a monochrome bitmap to color, it sets white bits (1) to the background color and black bits (0) to the foreground color. The foreground and background colors of the destination device context are used. To convert color to monochrome, BitBlt sets pixels that match the background color to white and sets all other pixels to black.BitBlt uses the foreground and background colors of the color device context to convert from color to monochrome.

翻译:如果目的,源和模式位图颜色模式不同,BitBlt 函数会转换源和模式位图,以适应目的位图。目的位图的前景色和背景色,应用在转换过程中。单色位图只有“1”和“0”两种像素值。

BitBlt函数转换“单色位图”(源)“彩色位图”(目的)时,会将“单色位图”中的“1”转化为背景色目的的背景色),“0”转化为前景色目的的前景色)。这里需要十分注意背景设置函数pdcDest->SetBkColor(…)和前景设置函数pdcDest->SetTextColor(…)的使用。

BitBlt函数转换“彩色位图”(源)“单色位图”(目的)时,将“彩色位图”中像素值等于“背景色”(通过pdcSource->SetBkColor(…)设置)的像素转化为“单色位图”中为“1”,其他的像素值变成了“0”。

测试图片:

bitblt函数 透明底图_手绘楼盘摆位图怎么画

测试代码:

	//第1步:加载源位图bitmapDest,选入内存设备dcDest
	CDC dcSource;
	dcSource.CreateCompatibleDC(pDC);
	CBitmap bitmapDest;
	bitmapDest.LoadBitmap(IDB_BITMAP3);
	CBitmap *pOldBitmapDest=dcSource.SelectObject(&bitmapDest);          //源位图 选到了设备上下文

	BITMAP bitmapInfo;                                                 //获取位图信息
	bitmapDest.GetBitmap(&bitmapInfo);


	//第2步:建立单值位图bitmapMonochrome,选入内存设备dcMonoChrome

	CDC dcMonoChrome;                       //单色设备上下文
	dcMonoChrome.CreateCompatibleDC(pDC);
	CBitmap bitmapMonochrome;
	bitmapMonochrome.CreateBitmap(bitmapInfo.bmWidth,bitmapInfo.bmHeight,1,1,NULL);
	CBitmap *pOldBitmapMonoChrome=dcMonoChrome.SelectObject(&bitmapMonochrome);        



	//第3步:彩色位图 -----------> 单色位图 

	///注意这里设置  源位图的背景色
	dcSource.SetBkColor(RGB(164,51,39));  

	//源位图中   像素值为(164,51,39)的 对应到单色位图中的1,其他值变为0
	dcMonoChrome.BitBlt(0,0,bitmapInfo.bmWidth,bitmapInfo.bmHeight,&dcSource,0,0,SRCCOPY);  


	第4步:画出转化后的单色图

	// pDC->BitBlt(50,50,bitmapInfo.bmWidth,bitmapInfo.bmHeight,&dcMonoChrome,0,0,SRCCOPY);

	//第5步:单色图   ---------->   彩色位图
	pDC->SetBkColor(RGB(220,216,67));                 //单色中的1--------------->(220,216,67)
	pDC->SetTextColor(RGB(173,98,50));                //单色中的0--------------->(173,98,50)
	pDC->BitBlt(50,50,bitmapInfo.bmWidth,bitmapInfo.bmHeight,&dcMonoChrome,0,0,SRCCOPY);



	//释放
	dcSource.SelectObject(pOldBitmapDest);
	bitmapDest.DeleteObject();
	dcSource.DeleteDC();

	 
	dcMonoChrome.SelectObject(&bitmapMonochrome); 
	bitmapMonochrome.DeleteObject();
	dcMonoChrome.DeleteDC();

结果分析:

bitblt函数 透明底图_手绘楼盘摆位图怎么画



彩色位图融合到彩色背景

返回文章开头提到的,棋子周围的图片透明处理。这里要借助单色位图,作为 “掩图”,去除棋子周围的透明区域。

性质1:二进制逻辑运算中,0[xor]0=0;0[xor]1=1,可见,“异或”操作中0具有保持原bit不变的性质。

性质2:1[xor]0[xor]0=1;1[xor]1[xor]1=1;0[xor]1[xor]1=0;0 [xor] 0[xor]0=0; 可见,一个bit1[xor]bit2[xor]bit2=bit1  连续“异或”,和“没有操作”一样。

借助一些小技巧,可以去掉图片周围的底色,现在有下面的“背景图”(A)和“源位图”(B),需要去掉“鸣人”周围的“棕红色”区域。

问题:根据性质2,A[异或]B[异或]B,可以去掉“棕红色”,但是糟糕的是“鸣人”也去掉了。

解决办法:在根据性质1,在第一次   [异或]B  后,将“鸣人”区域置为0,“棕红色”区域保持不变,办法是中间加上一个[与]操作。根据鸣人图片制作一个“掩码”图片,即图(C)。


图片叠加的步骤:A[异或]B[与]C[异或]B

bitblt函数 透明底图_手绘楼盘摆位图怎么画                

                             (A)            


 bitblt函数 透明底图_手绘楼盘摆位图怎么画


                        (B)


bitblt函数 透明底图_手绘楼盘摆位图怎么画


                           (C)

测试代码:

	//第1步:创建背景  
	CBitmap bitmapBack;
	bitmapBack.LoadBitmap(IDB_BEIJING);
	CDC dcMemBack;
	dcMemBack.CreateCompatibleDC(pDC);
	CBitmap *pOldBitmapBack=dcMemBack.SelectObject(&bitmapBack);

	BITMAP bitmapInfo;
	bitmapBack.GetBitmap(&bitmapInfo);

	//第2步:创建源图
	CBitmap bitmapSource;
	bitmapSource.LoadBitmap(IDB_BITMAP3);
	CDC  dcMemSource;
	dcMemSource.CreateCompatibleDC(pDC);
	CBitmap *pOldBitmapSource=dcMemSource.SelectObject(&bitmapSource);



	//第3步:创建单色图
	CBitmap  bitmapMonochrome;
	bitmapMonochrome.CreateBitmap(bitmapInfo.bmWidth,bitmapInfo.bmHeight,1,1,NULL);
	CDC  dcMemMonochrome;
	dcMemMonochrome.CreateCompatibleDC(pDC);
	CBitmap *pOldBitmapMonochrome=dcMemMonochrome.SelectObject(&bitmapMonochrome);

	//第4步:源位图----->单色图
	dcMemSource.SetBkColor(RGB(164,51,39));
	dcMemMonochrome.BitBlt(0,0,bitmapInfo.bmWidth,bitmapInfo.bmHeight,&dcMemSource,0,0,SRCCOPY);


	//第5步:“鸣人”透明叠加“背景”图中
	pDC->BitBlt(50,50,bitmapInfo.bmWidth,bitmapInfo.bmHeight,&dcMemBack,0,0,SRCCOPY);
	pDC->BitBlt(50,50,bitmapInfo.bmWidth,bitmapInfo.bmHeight,&dcMemSource,0,0,SRCINVERT);


	//注意这里涉及到将“单色位图”-------->“彩色位图”,然后在进行运算,
	//默认下背景色是(255,255,255),前景色是(0,0,0),下面两句可以不加,
	pDC->SetBkColor(RGB(255,255,255));   //将dcMemMonochrome中的“1”转化为(255,255,255)
	pDC->SetTextColor(RGB(0,0,0));       //将dcMemMonochrome中的“0”转化为(0,0,0)

	pDC->BitBlt(50,50,bitmapInfo.bmWidth,bitmapInfo.bmHeight,&dcMemMonochrome,0,0,SRCAND);


	pDC->BitBlt(50,50,bitmapInfo.bmWidth,bitmapInfo.bmHeight,&dcMemSource,0,0,SRCINVERT);


	//释放
	dcMemBack.SelectObject(pOldBitmapBack);
	bitmapBack.DeleteObject();
	dcMemBack.DeleteDC();
	
	dcMemSource.SelectObject(pOldBitmapSource);
	bitmapSource.DeleteObject();
	dcMemSource.DeleteDC();

	dcMemMonochrome.SelectObject(pOldBitmapMonochrome);
	bitmapMonochrome.DeleteObject();
	dcMemMonochrome.DeleteDC();

测试结果:

bitblt函数 透明底图_手绘楼盘摆位图怎么画



文中有错误的地方请留言!!!!





版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/180426.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 图解MySQL 内连接、外连接、左连接、右连接、全连接……太多了

    图解MySQL 内连接、外连接、左连接、右连接、全连接……太多了用两个表(a_table、b_table),关联字段a_table.a_id和b_table.b_id来演示一下MySQL的内连接、外连接(左(外)连接、右(外)连接、全(外)连接)。MySQL版本:Serverversion:5.6.31MySQLCommunityServer(GPL)数据库表:a_table、b_table主题:内连接、左连接(左外连

    2022年6月14日
    23
  • VMware Tools安装步骤(windows10)[通俗易懂]

    VMware Tools安装步骤(windows10)[通俗易懂]VMwareTools是VMware虚拟机中的一个工具,其主要作用是能够使鼠标在虚拟机和主机之前流畅地切换,并且能够共享剪贴板。我们可以通过VMwareTools将主机的文件复制粘贴到虚拟机。同时使得Ubuntu界面完全填充VMware界面在Windows10环境下,在电脑上安装VMware和Ubuntu的具体步骤可以看此篇博客:Windows环境下,在VMware中安装Ubuntu的详细步骤本文讲述了在VMware16.0.0,Ubuntu21.10环境下,VMwareTools的安装步骤。1

    2022年5月9日
    801
  • php把字符串转换为大写_金额大小写顺序

    php把字符串转换为大写_金额大小写顺序php金额大小写转换的方法:使用金额转换函数grees,代码为【$grees=array(“拾”,”佰”,”仟”,”万”,”拾”,”佰”,”仟”,”亿”);list($ns1,$ns2)=explode(“.”,$ns,2)】。php金额大小写转换的方法:早些年做CRM用到的一个金额转换函数,今天从旧项目中拿出来记录一下。金额转换的函数方法有很多,都很不错。不过这个是小崔刚工作的时候写的一个转换函…

    2022年10月6日
    0
  • win10关闭135 139 445端口_windows中如何关闭端口

    win10关闭135 139 445端口_windows中如何关闭端口关闭445端口-首先进入系统的”注册表编辑器“,步骤是:依次点击”开始“,”运行“,输入regedit进入”注册表编辑器“。之后依次点击注册表选项”HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\NetBT\Parameters“,进入NetBT这个服务的相关注册表项。在Parameters这个子项的右侧,点击鼠标右键,“新建”,“QWORD(64位)值”,然后重命名为“SMBDeviceEnabled”,再把这个子键的值改为0你还要做的就是

    2022年10月16日
    0
  • python pyc文件使用_python怎么打开pyc文件

    python pyc文件使用_python怎么打开pyc文件首先使用百度搜索“ultraEdit”,进入到如图所示的官网下载文件。进入到ultraEdit官网的下载界面,我们选择如图所示的试用版本下载,我们进入到具体的下载界面后,点击下载中文安装版。下载好,我们使用鼠标左键双击软件安装包,进入到安装界面后点击安装,使用默认安装就可以了,无需修改安装文件路径。安装好了后,我们在电脑桌面使用鼠标左键双击ultraEdit的快捷方式,打开后进入到ultraEdi…

    2022年6月24日
    34
  • mysql中phpmyadmin安装教程_phpMyAdmin 安装教程全攻略「建议收藏」

    mysql中phpmyadmin安装教程_phpMyAdmin 安装教程全攻略「建议收藏」管理MYSQL数据库的最好工具是PHPmyAdmin,现在最新版本是phpMyAdmin2.9.0.2,这是一个国际上开源的软件,一直在更新版本,你可以从http://www.phpmyadmin.net官方网站上下载到,安装后可以远程更新数据库(其实是在服务器上安装)。安装办法请参考:phpMyAdmin安装攻略1、先下载phpMyAdmin安装包,http://www.phpm…

    2022年5月31日
    31

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号