BitMask分析

来源:互联网 发布:定义变量不赋值js 编辑:程序博客网 时间:2024/05/22 01:27
//头文件
#include <Windows.h>
#include "resource.h"


//预处理
#ifdef UNICODE
#define CF_TCHAR CF_UNICODETEXT
#else
#define CF_TCHAR CF_TEXT
#endif


//全局变量
HINSTANCE hInst;
TCHAR szAppName[] = TEXT("BitMask");


//自定义函数
//1.功能:弹出对应数值的对话框
void MB_Value(int i)
{
TCHAR szBuffer[100];
wsprintf(szBuffer, TEXT("%d"), i);
MessageBox(0, szBuffer, szBuffer, 0);
}


//主窗口消息过程
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc, hdcMemImag, hdcMemMask;
PAINTSTRUCT ps;
static int cxClient, cyClient, cxBitmap, cyBitmap;
static HBITMAPhBitmapImag, hBitmapMask;
int x, y;
BITMAP bitmap;


switch (message)
{
case WM_CREATE:
//初始化2个位图, cxBitmap, cyBitmap
hBitmapImag = LoadBitmap(hInst, TEXT("MATTHEW"));
GetObject(hBitmapImag, sizeof(BITMAP), &bitmap);
cxBitmap = bitmap.bmWidth;
cyBitmap = bitmap.bmHeight;
hBitmapMask = CreateBitmap(cxBitmap, cyBitmap, 1, 1, 0);


//初始化2个Memory DC
hdcMemImag = CreateCompatibleDC(0);
hdcMemMask = CreateCompatibleDC(0);


//将位图载入DC
SelectObject(hdcMemImag, hBitmapImag);
SelectObject(hdcMemMask, hBitmapMask);


//绘制hBitmapMask位图
SelectObject(hdcMemMask, GetStockObject(BLACK_BRUSH));
Rectangle(hdcMemMask, 0, 0, cxBitmap, cyBitmap);//黑色矩形
SelectObject(hdcMemMask, GetStockObject(WHITE_BRUSH));
Ellipse(hdcMemMask, 0, 0, cxBitmap, cyBitmap);//白色椭圆


//对第一个位图进行位运算
// 使用AND(与)操作符来将模板传送到原始位图上
// 由于模板位图是单色的,所以白色为1,黑色为0。通过AND操作,删除了源位图中椭圆以外的图素
BitBlt(hdcMemImag, 0, 0, cxBitmap, cyBitmap, hdcMemMask, 0, 0, SRCAND);

//左边是现在的hBitmapImag//右边是hBiutmapMask


// 删除内存环境,得到了黑色包围的椭圆区域位图hdcMemImag
DeleteObject(hdcMemImag);
DeleteObject(hdcMemMask);


return 0;
case WM_SIZE:
//窗口大小发生变化时
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);


return 0;
case WM_PAINT:
//窗口重新绘制时
hdc = BeginPaint(hwnd, &ps);
//Select bitmaps in to memory DCs


// 用于传送最终位图的内存环境
hdcMemImag = CreateCompatibleDC(hdc);
SelectObject(hdcMemImag, hBitmapImag);


// 用于设置背景色的内存环境
hdcMemMask = CreateCompatibleDC(hdc);
SelectObject(hdcMemMask, hBitmapMask);


//Center image
// 窗口大小 减去 位图大小 除以2 得到除开位图的平均中心区域,用于中心显示位图
x = (cxClient - cxBitmap) / 2;
y = (cyClient - cyBitmap) / 2;


//do the bit
// 0x220326 所执行的操作为 D & !S(先将模板图素(hdcBitmapMask)取反 ,再与程序窗体色进行位AND运算后合并)
// 该操作先将原来黑色包围白色椭圆的位图,变为白色包围黑色椭圆的位图
// 最后通过AND合并,黑色为0。所以得到一个程序窗口中心为黑色椭圆的窗口画面

//左边是现在的hBitmapImag//右边是hBitmapMask
BitBlt(hdc, x, y, cxBitmap, cyBitmap, hdcMemMask, 0, 0, 0x220326);

取反

// BitBlt(hdc, x, y, cxBitmap, cyBitmap, hdcMemMask, 0, 0, SRCCOPY);


// BitBlt(hdc, x, y, cxBitmap, cyBitmap, hdcMemImag, 0, 0, SRCCOPY);
// SRCPAINT 在来源和目的之间进行位OR操作
// 由于该位图在椭圆以外为黑色0,OR保持了程序窗口原始色彩不变
// 最终将这个修改过的椭圆位图,显示到了窗口中心区域


BitBlt(hdc, x, y, cxBitmap, cyBitmap, hdcMemImag, 0, 0, SRCPAINT);

OR

最后的结果就为


DeleteDC(hdcMemImag);
DeleteDC(hdcMemMask);


EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
//退出清除
DeleteObject(hBitmapImag);
DeleteObject(hBitmapMask);
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}


//程序入口
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLines, int iCmdShow)
{
hInst = hInstance;
HWND hwnd;
MSG msg;
WNDCLASS wndclass;


wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = szAppName;
wndclass.lpszMenuName = NULL;


if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("The program requires Window NT!"), szAppName, MB_ICONERROR);
return 0;
}


hwnd = CreateWindow(szAppName,
TEXT("Bitmap Masking Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);


ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);


while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}


return msg.wParam;
}
0 0
原创粉丝点击