《Windows程序设计》之BITMASK

本文介绍了一种使用Windows GDI进行位图合成的方法,包括如何创建位图及内存设备上下文,实现图片的裁剪与合成效果,以及如何通过掩码技术使图像呈现特定形状。

对位图中的掩码图,或图片合成还需要做进一步的了解,继续熟悉了内存中图片处理的相应过程。


LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	static HBITMAP hBitmapImag,hBitmapMask;
	static HINSTANCE hInstance;
	static int cxClient,cyClient,cxBitmap,cyBitmap;
	BITMAP bitmap;
	HDC hdc,hdcMemImag,hdcMemMask;
	int x,y;
	PAINTSTRUCT ps;

	switch(message)
	{
	case WM_CREATE:
		//实例句柄
		hInstance=((LPCREATESTRUCT)lParam)->hInstance;
		//图片句柄
		hBitmapImag=LoadBitmap(hInstance,TEXT("Matthew"));
		//图片相关信息
		GetObject(hBitmapImag,sizeof(BITMAP),&bitmap);
		cxBitmap=bitmap.bmWidth;
		cyBitmap=bitmap.bmHeight;
		//创建内存设备上下文
		hdcMemImag=CreateCompatibleDC(NULL);
		//图片选入内存设备
		SelectObject(hdcMemImag,hBitmapImag);
		//创建一个图片
		hBitmapMask=CreateBitmap(cxBitmap,cyBitmap,1,1,NULL);
		//创建内存设备上下文
		hdcMemMask=CreateCompatibleDC(NULL);
		//选入设备上下文
		SelectObject(hdcMemMask,hBitmapMask);
		//对内存设备选入黑色画刷
		SelectObject(hdcMemMask,GetStockObject(BLACK_BRUSH));
		//画矩形
		Rectangle(hdcMemMask,0,0,cxBitmap,cyBitmap);
		//选入白色画刷
		SelectObject(hdcMemMask,GetStockObject(WHITE_BRUSH));
		//画椭圆
		Ellipse(hdcMemMask,0,0,cxBitmap,cyBitmap);
		//由hdcMemImag中的位图移动到hdcMemMask中,与原位图做AND运算
		BitBlt(hdcMemImag,0,0,cxBitmap,cyBitmap,hdcMemMask,0,0,SRCAND);

		DeleteDC(hdcMemImag);
		DeleteDC(hdcMemMask);
		return 0;
	case WM_SIZE:
		cxClient=LOWORD(lParam);
		cyClient=HIWORD(lParam);
		return 0;
	case WM_PAINT:
		hdc=BeginPaint(hwnd,&ps);
		//要显示了,创建与显示相关的内存设备上下文
		hdcMemImag=CreateCompatibleDC(hdc);
		//hBitmapImag这个句柄是不会变的,创建时的相当操作改变了hBitmapImag的内容,但没有改变句柄
		SelectObject(hdcMemImag,hBitmapImag);

		hdcMemMask=CreateCompatibleDC(hdc);
		SelectObject(hdcMemMask,hBitmapMask);

		x=(cxClient-cxBitmap)/2;
		y=(cyClient-cyBitmap)/2;

		//下面这一行,使得椭圆内部为黑色,其它地方为浅色
		BitBlt(hdc,x,y,cxBitmap,cyBitmap,hdcMemMask,0,0,0x220326);
		//做或运算,合成图像
		BitBlt(hdc,x,y,cxBitmap,cyBitmap,hdcMemImag,0,0,SRCPAINT);

		DeleteDC(hdcMemImag);
		DeleteDC(hdcMemMask);
		EndPaint(hwnd,&ps);
		return 0;
	case WM_DESTROY:
		DeleteObject(hBitmapImag);
		DeleteObject(hBitmapMask);
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd,message,wParam,lParam);
}



### UE4 中的 Bitmask 使用与实现 #### 什么是 Bitmask? 在 Unreal Engine 4 (UE4) 中,位掩码(Bitmask)是一种用于高效管理和操作一组布尔标志的技术。通过将多个标志存储在一个整数中,可以显著减少内存占用并提高处理速度。 #### 如何声明和使用 Bitmask 属性 属性现在可以被声明为位掩码,并可以选择关联枚举来封装位标志值[^1]。这种特性不仅适用于 C++ 编程,也支持蓝图脚本系统的使用: ```cpp UENUM() enum class EMyFlags : uint8 { None UMETA(Hidden), FlagOne = 0x1, FlagTwo = 0x2, FlagThree= 0x4, }; UPROPERTY(EditAnywhere, BlueprintReadWrite) TEnumAsByte<EMyFlags> MyFlag; ``` 上述代码展示了如何定义一个带有三个可能状态的位标记集合 `EMyFlags` 并将其应用于类成员变量 `MyFlag` 上。 #### 基础位运算示例 为了更好地理解位掩码的操作方式,在下面的例子中定义了一些常量 BIT_0 到 BIT_7 来代表不同的二进制位置;初始化了一个名为 `bitmask` 的位掩码变量设为零;接着利用按位或运算符设置了特定的位置;最后借助于按位与运算符检测某一位是否已被激活[^2]: ```cpp const int32 BIT_0 = 1 << 0; // Binary: 00000001 const int32 BIT_1 = 1 << 1; // Binary: 00000010 // ... up to ... const int32 BIT_7 = 1 << 7; // Binary: 10000000 int32 bitmask = 0; // Set specific bits using bitwise OR operator bitmask |= BIT_0 | BIT_2; // Check if a particular bit is set using bitwise AND operator bool IsBitSet(int32 mask, int32 flag){ return ((mask & flag) != 0); } ``` 这段简单的例子说明了怎样创建以及查询位掩码内的单个旗标。 #### Vulkan 图像用途中的注意事项 当涉及到图形 API 如 Vulkan 时,如果图像用途包含了 `VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT` ,那么除了颜色附件、深度模板附件及输入附件之外其他任何位都不能被设置[^3]。这表明对于临时附加使用的纹理资源来说,其允许的功能范围受到了严格限制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值