#include <windows.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

HBITMAP g_bmp;
HBITMAP g_bmpMask; HBITMAP createImageMask(HBITMAP bitmapHandle, const COLORREF transparencyColor) {
// For getting information about the bitmap's height and width in this context
BITMAP bitmap; // Create the device contexts for the bitmap and its mask
HDC bitmapGraphicsDeviceContext = CreateCompatibleDC(NULL);
HDC bitmapMaskGraphicsDeviceContext = CreateCompatibleDC(NULL); // The actual mask
HBITMAP bitmapMaskHandle; // 1. Generate the mask.
GetObject(bitmapHandle, sizeof(BITMAP), &bitmap);
bitmapMaskHandle = CreateBitmap(bitmap.bmWidth, bitmap.bmHeight, , , NULL); // 2. Setup the device context for the mask (and the bitmap).
SelectObject(bitmapGraphicsDeviceContext, bitmapHandle);
SelectObject(bitmapMaskGraphicsDeviceContext, bitmapMaskHandle); // 3. Set the background color of the mask.
SetBkColor(bitmapGraphicsDeviceContext, transparencyColor); // 4. Copy the bitmap to the mask and invert it so it blends with the background color.
BitBlt(bitmapMaskGraphicsDeviceContext, , , bitmap.bmWidth, bitmap.bmHeight, bitmapGraphicsDeviceContext, , , SRCCOPY);
BitBlt(bitmapGraphicsDeviceContext, , , bitmap.bmWidth, bitmap.bmHeight, bitmapMaskGraphicsDeviceContext, , , SRCINVERT); // Clean-up
DeleteDC(bitmapGraphicsDeviceContext);
DeleteDC(bitmapMaskGraphicsDeviceContext); // Voila!
return bitmapMaskHandle;
} int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{ MSG msg = { };
WNDCLASS wc = { };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = L"minwindowsapp"; g_bmp = (HBITMAP)LoadImage(hInstance, L"C:\\Users\\h2fM6d9.bmp", IMAGE_BITMAP, , , LR_LOADFROMFILE);
g_bmpMask = createImageMask(g_bmp, RGB(, , )); if (!RegisterClass(&wc))
return ; if (!CreateWindow(wc.lpszClassName,
L"Minimal Windows Application",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
, , , , , , hInstance, NULL))
return ; while (GetMessage(&msg, NULL, , ) > ) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return ;
} LRESULT HandleWmPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps; HDC hdcScr = GetDC(NULL);
HDC hdcBmp = CreateCompatibleDC(hdcScr);
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcBmp, g_bmp); HDC hdcMask = CreateCompatibleDC(hdcScr);
HBITMAP hbmOldMask = (HBITMAP)SelectObject(hdcMask, g_bmpMask); HDC hdc = BeginPaint(hWnd, &ps);
BitBlt(hdc, , , , , hdcMask, , , SRCCOPY);
BitBlt(hdc, , , , , hdcBmp, , , SRCCOPY);
EndPaint(hWnd, &ps); SelectObject(hdcMask, hbmOldMask);
DeleteDC(hdcMask); SelectObject(hdcBmp, hbmOld);
DeleteDC(hdcBmp);
ReleaseDC(NULL, hdcScr); return ;
} LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ switch (message)
{
case WM_CLOSE:
PostQuitMessage();
break; case WM_PAINT:
return HandleWmPaint(hWnd, wParam, lParam); default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return ;
}

顺便说一句,这项技术是一种非常古老的实现方法,在GDI中引入的MaskBlt 可以取代它,它可以在一个调用中完成您想要的操作。但更进一步,MaskBlt在这一点上已经过时了。如果是想为游戏或类似游戏的游戏绘制精灵。实际上可能想要的是使用每个像素的Alpha加载PNG,并使用Alpha合成对其进行绘制。也可以使用GDI +或诸如FreeImage之类的开源图形库来实现。

GDI根据位图和透明度创建蒙版的更多相关文章

  1. iOS 通过有alpha值的图片创建蒙版

    @interface ViewController () @property (nonatomic, weak) IBOutlet UIImageView *imageView; @end @impl ...

  2. SVG图形引用、裁切、蒙版

    SVG图形引用.裁切.蒙版,使用三个标签: 1. <use>标签创建图形引用 2. <clipPath>标签裁切图形 3. <mask>标签创建蒙版  ...

  3. Quartz2D 编程指南(四)位图与图像遮罩、CoreGraphics 绘制 Layer

    概览 图形上下文 路径 颜色与颜色空间 变换 图案 阴影 渐变 透明层 Quartz 2D 中的数据管理 位图与图像遮罩 CoreGraphics 绘制 Layer 位图与图像遮罩 简介 位图与图像遮 ...

  4. 第15章 设备无关位图_15.3 DIB和DDB的结合

    第15章 设备相关位图_15.3 DIB和DDB的结合 15.3.1 从DIB创建DDB (1)hBitmap =CreateDIBitmap(…)——注意这名称会误导,实际上创建的是DDB 参数 说 ...

  5. GDI+中发生一般性错误的解决办法(转帖)

    今天在开发.net引用程序中,需要System.Drawing.Image.Save 创建图片,debug的时候程序一切正常,可是发布到IIS后缺提示出现“GDI+中发生一般性错误”的异常.于是开始“ ...

  6. VB6 GDI+ 入门教程[2] GDI+初始化

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[2] GDI+初始化 2009 年 6 月 18 日 7 ...

  7. C#-gdi绘图,双缓冲绘图,Paint事件的触发

    一. 画面闪烁问题与双缓冲技术 1.1 导致画面闪烁的关键原因分析: 1  绘制窗口由于大小位置状态改变进行重绘操作时 绘图窗口内容或大小每改变一次,都要调用Paint事件进行重绘操作,该操作会使画面 ...

  8. [转载]GDI+中发生一般性错误

    注:第一次写博客,把自己遇到的问题和收集的资料记录在博客上.在开发.NET应用中,使用 System.Drawing.Image.Save 方法而导致“GDI+ 中发生一般性错误”的发生,通常有以下三 ...

  9. GDI编程

    图形设备接口(GDI)是一个可执行程序,它接受Windows应用程序的绘图请求(表现为GDI函数调用),并将它们传给相应的设备驱动程序,完成特定于硬件的输出,象打印机输出和屏幕输出.GDI负责Wind ...

随机推荐

  1. ie兼容promise

    引入 <script src = "https://cdn.polyfill.io/v2/polyfill.min.js"></script> 或 < ...

  2. spring的控制器如何跳转到指定的视图

    1.控制器代码 2.跳转代码 return "greeting"; 引号内为跳转的页面,默认不需要加html

  3. 第07组 Alpha冲刺(1/4)

    队名:秃头小队 组长博客 作业博客 组长徐俊杰 过去两天完成的任务:完成人员分配,初步学习Android开发 Github签入记录 接下来的计划:继续完成Android开发的学习,带领团队进行前后端开 ...

  4. 《你必须知道的495个C语言问题》读书笔记之第15-20章:浮点数、风格、杂项

    一.可变参数列表 1. Q:为什么调用printf前必须要包含<stdio.h>? A:为了把printf的正确原型说明引入作用域.例如,如果可变参数的调用比固定参数的调用效率低,编译器就 ...

  5. go 二进制数据处理

    以下是利用标准库binary来进行编解码 编码 ①使用bytes.Buffer来存储编码生成的串②使用binary.Write来编码存储在①的buf中 package main import ( &q ...

  6. TCP的socket连接

    package newtest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStre ...

  7. 新拉的项目在idea中启动时报如下错误:org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:

    今天真的是很苦恼,之前启动项目没有任何问题,今天突然启动时给我报了如下一个错误. 详细报错信息: org.apache.catalina.core.ContainerBase.addChildInte ...

  8. 【51nod】2564 格子染色

    [51nod]2564 格子染色 这道题原来是网络流-- 感觉我网络流水平不行-- 这种只有两种选择的可以源点向该点连一条容量为b的边,该点向汇点连一条容量为w的边,如果割掉了b证明选w,如果割掉了w ...

  9. Kubernetes---容器探针

    ⒈含义 探针是由各个节点的kubelet对容器执行的定期诊断.要执行诊断,kubelet 调用由容器实现的Handler[处理程序].有三种类型的处理程序: >ExecAction:在容器内执行 ...

  10. Swagger学习(三、配置扫描接口)

    生产环境中使用,发布的时候不能使用