GDI根据位图和透明度创建蒙版
#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根据位图和透明度创建蒙版的更多相关文章
- iOS 通过有alpha值的图片创建蒙版
@interface ViewController () @property (nonatomic, weak) IBOutlet UIImageView *imageView; @end @impl ...
- SVG图形引用、裁切、蒙版
SVG图形引用.裁切.蒙版,使用三个标签: 1. <use>标签创建图形引用 2. <clipPath>标签裁切图形 3. <mask>标签创建蒙版 ...
- Quartz2D 编程指南(四)位图与图像遮罩、CoreGraphics 绘制 Layer
概览 图形上下文 路径 颜色与颜色空间 变换 图案 阴影 渐变 透明层 Quartz 2D 中的数据管理 位图与图像遮罩 CoreGraphics 绘制 Layer 位图与图像遮罩 简介 位图与图像遮 ...
- 第15章 设备无关位图_15.3 DIB和DDB的结合
第15章 设备相关位图_15.3 DIB和DDB的结合 15.3.1 从DIB创建DDB (1)hBitmap =CreateDIBitmap(…)——注意这名称会误导,实际上创建的是DDB 参数 说 ...
- GDI+中发生一般性错误的解决办法(转帖)
今天在开发.net引用程序中,需要System.Drawing.Image.Save 创建图片,debug的时候程序一切正常,可是发布到IIS后缺提示出现“GDI+中发生一般性错误”的异常.于是开始“ ...
- VB6 GDI+ 入门教程[2] GDI+初始化
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[2] GDI+初始化 2009 年 6 月 18 日 7 ...
- C#-gdi绘图,双缓冲绘图,Paint事件的触发
一. 画面闪烁问题与双缓冲技术 1.1 导致画面闪烁的关键原因分析: 1 绘制窗口由于大小位置状态改变进行重绘操作时 绘图窗口内容或大小每改变一次,都要调用Paint事件进行重绘操作,该操作会使画面 ...
- [转载]GDI+中发生一般性错误
注:第一次写博客,把自己遇到的问题和收集的资料记录在博客上.在开发.NET应用中,使用 System.Drawing.Image.Save 方法而导致“GDI+ 中发生一般性错误”的发生,通常有以下三 ...
- GDI编程
图形设备接口(GDI)是一个可执行程序,它接受Windows应用程序的绘图请求(表现为GDI函数调用),并将它们传给相应的设备驱动程序,完成特定于硬件的输出,象打印机输出和屏幕输出.GDI负责Wind ...
随机推荐
- TMS320C6455小介绍
TMS320C6455是TI公司推出的的一款新型高性能单核定点DSP.它是TI公司基于第三代先进VeloviTI VLIW(超长指令字)结构开发出来的新产品,在通信,医疗图像,无线传输方面都可以大有作 ...
- CQRS1
CQRS之旅——旅程1(我们的领域:Contoso会议管理系统) 旅程1:我们的领域:Contoso会议管理系统 起点:我们从哪里来,我们带来了什么,谁将与我们同行?“ 只要前进,我愿意去任何地方 ...
- Springboot 使用Jwt token失效时接口无响应(乌龙)
问题背景:新项目使用Springboot框架,鉴权使用了Jwt 处理cors: @Configuration public class WebMvcConfig implements WebMvcCo ...
- bitmap位图原理和实现
引子 首先通过一道题来理解什么是bitmap. 题目:我有40亿个整数,再给一个新的整数,我需要判断新的整数是否在40亿个整数中,你会怎么做? 分析: 假设一个int占4个字节(32位),40个亿个整 ...
- [Cometoj#3 A]比赛_枚举/堆
比赛 题目链接:https://cometoj.com/contest/38/problem/A?problem_id=1534 数据范围:略. 题解: 原题没啥意思,就是个暴力枚举. 出了个加强版, ...
- Linux下安装jdk中遇到的坑
比如:我以jdk-8u211-linux-i586.tar.gz为例进行. 下载完成后解压到指定文件下先创建java文件目录,如果已存在就不用创建[root@lyh:] # mkdir -p /usr ...
- DP的初级问题——01包、最长公共子序列、完全背包、01包value、多重部分和、最长上升子序列、划分数问题、多重集组合数
当初学者最开始学习 dp 的时候往往接触的是一大堆的 背包 dp 问题, 那么我们在这里就不妨讨论一下常见的几种背包的 dp 问题: 初级的时候背包 dp 就完全相当于BFS DFS 进行搜索之后的记 ...
- selenium登录4399
from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from seleni ...
- cygwin gcc 编译windowsAPI 报错的一个解决方案
一开始按照linux的习惯去编译一个使用了windowsAPI的程序 结果提示: $ i686-pc-cygwin-g++ screen_catch.cscreen_catch.c: In funct ...
- 论文阅读:Adaptive NMS: Refining Pedestrian Detection in a Crowd
论文阅读:Adaptive NMS: Refining Pedestrian Detection in a Crowd 2019年04月11日 23:08:02 Kivee123 阅读数 836 ...