VC++图片透明技术原理-创新互联

透明效果

成都创新互联是一家专业提供秦淮企业网站建设,专注与成都网站建设、成都做网站、html5、小程序制作等业务。10年已为秦淮众多企业、政府机构等服务。创新互联专业网站建设公司优惠进行中。

由于所有的图文件都是以矩形来储存的,我们也许会需要把一张易拉罐图片贴到窗口的背景图上,而这种情况下如果直接进行贴图,结果如下图:

VC++图片透明技术原理

这似乎不是我们想要的结果。

为了得到透明效果,我们需要运用到BitBlt()贴图函数以及其参数Raster的值来将图片中不必要的部分去掉(又称去背),使得图中的主题可以与背景完美融合。

制作透明效果有很多种方法,但是基本上都是利用贴图时不同的Raster运算,通过转换而产生相同的透明效果。在这里先来介绍一种透明运算的方法。

我们以图中的易拉罐为例子,首先准备一张位图,如下图。

VC++图片透明技术原理

图中的左边的图是要去背并贴到背景上的前景图。右边的黑白图称为“屏蔽图”,在透明的过程中会用到它。要把去背的位图与屏蔽图合并成同一张图,透明的时候再按照需要来进行裁切。可以把它分成两张图,但是这样程序必须运行两次图文件加载的操作。

有了屏蔽图就可以利用贴图函数来产生透明效果了,所需的贴图步骤如下:

<1>将屏蔽图与背景图做"AND"运算,Raster值为SRCAND,贴到目的地DC中。

<2>将前景图与背景图做"OR"运算,Raster值为SRCPAINT,贴到目的地DC中。

为什么经过上面两个操作就能产生透明的效果呢?看下图就理解了:

VC++图片透明技术原理

下面具体说明上面两个步骤所产生的图点色彩的变化。

1.屏蔽图与背景图做"AND"运算

<1>屏蔽图中的黑色部分与背景图做"AND"运算:

VC++图片透明技术原理

<2>屏蔽图中的白色部分与背景图做"AND"运算:

VC++图片透明技术原理

进过这一运算所产生的结果如下图

VC++图片透明技术原理

2.前景图与背景图做"OR"运算

<1>前景图中的彩色部分与图第一步得到的“黑色易拉罐”图做"OR"运算:

VC++图片透明技术原理

<2>前景图中的黑色部分与第一步得到的“黑色易拉罐”图做"OR"运算:

VC++图片透明技术原理

经过这一运算后所显示的画面就是所需的透明图了,如下图所示:

VC++图片透明技术原理

下面我们来看看实现上述透明贴图效果的源代码

[cpp] view plaincopy

  1. #include "stdafx.h"

  2. //全局变量声明

  3. HINSTANCE hInst;

  4. HBITMAP bg,sprite;        //声明两个位图对象,分别存储背景图与前景易拉罐

  5. HDC  mdc;       //声明一个内存DC"mdc",用来暂存位图

  6. //全局函数声明

  7. ATOM     MyRegisterClass(HINSTANCE hInstance);

  8. BOOL     InitInstance(HINSTANCE, int);

  9. LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

  10. void     MyPaint(HDC hdc);

  11. ////****Winmain函数,程序入口点函数**************************************

  12. int APIENTRY WinMain(HINSTANCE hInstance,

  13.                      HINSTANCE hPrevInstance,

  14.                      LPSTR     lpCmdLine,

  15.                      int       nCmdShow)

  16. {

  17. MSG msg;

  18. MyRegisterClass(hInstance);

  19. if (!InitInstance (hInstance, nCmdShow))

  20. {

  21. return FALSE;

  22. }

  23. //消息循环

  24. while (GetMessage(&msg, NULL, 0, 0))

  25. {

  26. TranslateMessage(&msg);

  27. DispatchMessage(&msg);

  28. }

  29. return msg.wParam;

  30. }

  31. //****设计一个窗口类,类似填空题,使用窗口结构体*************************

  32. ATOM MyRegisterClass(HINSTANCE hInstance)

  33. {

  34. WNDCLASSEX wcex;

  35. wcex.cbSize = sizeof(WNDCLASSEX);

  36. wcex.style   = CS_HREDRAW | CS_VREDRAW;

  37. wcex.lpfnWndProc    = (WNDPROC)WndProc;

  38. wcex.cbClsExtra  = 0;

  39. wcex.cbWndExtra  = 0;

  40. wcex.hInstance   = hInstance;

  41. wcex.hIcon   = NULL;

  42. wcex.hCursor     = NULL;

  43. wcex.hCursor     = LoadCursor(NULL, IDC_ARROW);

  44. wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);

  45. wcex.lpszMenuName   = NULL;

  46. wcex.lpszClassName  = "canvas";

  47. wcex.hIconSm     = NULL;

  48. return RegisterClassEx(&wcex);

  49. }

  50. //****初始化函数*************************************

  51. // 1.建立与窗口DC兼容的内存DC

  52. // 2.从文件加载背景图与恐龙图

  53. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

  54. {

  55. HWND hWnd;

  56. HDC hdc;

  57. hInst = hInstance;

  58. hWnd = CreateWindow("canvas", "绘图窗口" , WS_OVERLAPPEDWINDOW,

  59. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

  60. if (!hWnd)

  61. {

  62. return FALSE;

  63. }

  64. MoveWindow(hWnd,10,10,600,450,true);

  65. ShowWindow(hWnd, nCmdShow);

  66. UpdateWindow(hWnd);

  67. hdc = GetDC(hWnd);                     //获得窗口DC

  68. mdc = CreateCompatibleDC(hdc);           //创建与窗口兼容的内存DC(mdc)

  69. bg = (HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,600,450,LR_LOADFROMFILE);

  70. //J加载背景图到bg中

  71. sprite = (HBITMAP)LoadImage(NULL,"sprite.bmp",IMAGE_BITMAP,170,99,LR_LOADFROMFILE);

  72. //加载易拉罐图到sprite中

  73. MyPaint(hdc);

  74. ReleaseDC(hWnd,hdc);

  75. return TRUE;

  76. }

  77. //****自定义绘图函数*********************************

  78. //透明贴图

  79. void MyPaint(HDC hdc)

  80. {

  81. SelectObject(mdc,bg);

  82. BitBlt(hdc,0,0,600,450,mdc,0,0,SRCCOPY);    //先将背景图贴到显示窗口中

  83. SelectObject(mdc,sprite);                      //选用易拉罐图到"mdc"中

  84. BitBlt(hdc,50,50,225,225,mdc,225,0,SRCAND);//进行制作贴图的第一步骤,即将屏蔽图与背景图做"AND"运算,屏蔽图在整张易拉罐图中,最左上角起始位置点得坐标为(225,0),BitBlt()函数中最后一个Raster参数值设置为SRCAND。

  85. BitBlt(hdc,50,50,225,225,mdc,0,0,SRCPAINT);//进行制作透明贴图的第二步骤,即将前景图与背景图做"OR"运算,前景图在整张易拉罐图中,最左上角起始位置的坐标为(0,0),BitBlt()函数最后一个参数值设置为SRCPAINT。

  86. }

  87. //****消息处理函数**********************************

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

  89. {

  90. PAINTSTRUCT ps;

  91. HDC hdc;

  92. switch (message)

  93. {

  94. case WM_PAINT:   //窗口重绘消息

  95. hdc = BeginPaint(hWnd, &ps);

  96. MyPaint(hdc);

  97. EndPaint(hWnd, &ps);

  98. break;

  99. case WM_DESTROY:     //窗口结束消息

  100. DeleteDC(mdc);

  101. DeleteObject(bg);

  102. DeleteObject(sprite);

  103. PostQuitMessage(0);

  104. break;

  105. default:     //其他消息

  106. return DefWindowProc(hWnd, message, wParam, lParam);

  107.    }

  108.    return 0;

  109. }

最后程序的运行结果为:

VC++图片透明技术原理

通过BitBlt()贴图函数及Raster运算值的设定,很简单地就做出了想要的透明效果,这种方法在设计2D游戏的一些画面内容时使用相当频繁。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前题目:VC++图片透明技术原理-创新互联
本文来源:http://pwwzsj.com/article/ccgogh.html