[游戏模版9] Win32 半透明 图像处理


 

>_<:Previous part we talk about how to map a transparent picture, and this time we will solve the problem how to change a picture's transparency.

>_<:Here my method is reading the picture's information and change its RGB or add another picture's RGB to it according to certain proportion(here result must between 0~255, like following example you can let background picture's RGB multiply by 0.7 and wanted picture's RGB multiply by 0.3), then map it on window.

>_<:Here is the method introduction:

  • firstly: load picture to handle:
  • bg=(HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,600,450,LR_LOADFROMFILE);

 

  • secondly:get the picture information to bm1 (suggestion find the knowledge about bitmap struct and it's better to know how computer save .bmp picture)
  • BITMAP bm1;
  • GetObject(bg,sizeof(BITMAP),&bm1);

 

  • Thirdly:ensure whether the picture is suit for this model.
1 if(bm1.bmBitsPixel!=32 && bm1.bmBitsPixel!=24)
2 {
3     MessageBox(NULL,"此程序只能在 32 bit 或 24 bit 显示模式中运行","警告",0);
4     return FALSE;
5 }
  • Fourthly:get the RGB of .bmp picture saving it in unsigned char array.
1 unsigned char *px1=new unsigned char[bm1.bmHeight * bm1.bmWidthBytes];
2 GetBitmapBits(bg,bm1.bmHeight*bm1.bmWidthBytes,px1);
  • Fifthly:use the same way to  deal with another picture that you want to change transparency,the first one show as background.
1 dra=(HBITMAP)LoadImage(NULL,"dra.bmp",IMAGE_BITMAP,243,120,LR_LOADFROMFILE);
2 GetObject(dra,sizeof(BITMAP),&bm2);
3 px2=new unsigned char[bm2.bmHeight * bm2.bmWidthBytes];
4 GetBitmapBits(dra,bm2.bmHeight*bm2.bmWidthBytes,px2);
  • Sixth:according to wanted transparent picture's lenth and width change corresponding background picture's char array's RGB value.At the same time changing this picture's char array's value,and after this step operation the px2 array will including the already-seted-transparency picture information.
 1 int xend,yend;
 2 int x,y,i;
 3 int rgb_b;
 4 int PxBytes=bm1.bmBitsPixel/8;
 5 
 6 xend=xstart+298;
 7 yend=ystart+329;
 8 
 9 for(y=ystart;y<yend;y++)
10 {
11    for(x=xstart;x<xend;x++)
12    {
13        rgb_b=y*bm1.bmWidthBytes+x*PxBytes;
14 
15        px1[rgb_b]=px1[rgb_b]*0.7;
16        px1[rgb_b+1]=px1[rgb_b+1]*0.7;
17        px1[rgb_b+2]=px1[rgb_b+2]*0.7;
18    }
19 }
20 
21 
22 for(y=0;y<(bm2.bmHeight);y++)
23 {
24    for(x=0;x<bm2.bmWidth;x++)
25    {
26        rgb_b=y*bm2.bmWidthBytes+x*PxBytes;
27        i=(ystart+y)*bm1.bmWidthBytes+(xstart+x)*PxBytes;
28 
29        px2[rgb_b]=px2[rgb_b]*0.3+px1[i];
30        px2[rgb_b+1]=px2[rgb_b+1]*0.3+px1[i+1];
31        px2[rgb_b+2]=px2[rgb_b+2]*0.3+px1[i+2];
32    }
33 }
  • Finally:use px2[] to reflash dra and make the handle dra include new seted-transparency picture's information.
1 SetBitmapBits(dra,bm2.bmHeight*bm2.bmWidthBytes,px2);

>_<:now the handle of bg.bmp is in bg;the handle of seted-transparency dra.bmp is in dra.Next,you can directly map them on window's dc.

1 void MyPaint(HDC hdc)
2 {
3     SelectObject(mdc,bg);
4     BitBlt(hdc,0,0,1366,768,mdc,0,0,SRCCOPY);//在窗口位置、大小、原图剪切位
5 
6     SelectObject(mdc,dra);
7     BitBlt(hdc,xstart,ystart,121,120,mdc,0,0,SRCCOPY);
8 }

 >_<:Here is all the code:

 1 //{{NO_DEPENDENCIES}}
 2 // Microsoft Visual C++ generated include file.
 3 // Used by FE.RC
 4 //
 5 #define IDR_MAINFRAME                    128
 6 #define IDD_FE_DIALOG        102
 7 #define IDD_ABOUTBOX                    103
 8 #define IDS_APP_TITLE                    103
 9 #define IDM_ABOUT                        104
10 #define IDM_EXIT                        105
11 #define IDS_HELLO                        106
12 #define IDI_FE                107
13 #define IDI_SMALL                        108
14 #define IDC_FE                109
15 #define IDC_MYICON                        2
16 #define IDC_STATIC                        -1
17 // Next default values for new objects
18 //
19 #ifdef APSTUDIO_INVOKED
20 #ifndef APSTUDIO_READONLY_SYMBOLS
21 
22 #define _APS_NEXT_RESOURCE_VALUE        129
23 #define _APS_NEXT_COMMAND_VALUE         32771
24 #define _APS_NEXT_CONTROL_VALUE         1000
25 #define _APS_NEXT_SYMED_VALUE           110
26 #endif
27 #endif
resourse.h
 1 // stdafx.h : include file for standard system include files,
 2 //  or project specific include files that are used frequently, but
 3 //      are changed infrequently
 4 //
 5 
 6 #if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
 7 #define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_
 8 
 9 #if _MSC_VER > 1000
10 #pragma once
11 #endif // _MSC_VER > 1000
12 
13 #define WIN32_LEAN_AND_MEAN        // Exclude rarely-used stuff from Windows headers
14 
15 
16 // Windows Header Files:
17 #include <windows.h>
18 
19 // C RunTime Header Files
20 #include <stdlib.h>
21 #include <malloc.h>
22 #include <memory.h>
23 #include <tchar.h>
24 
25 // Local Header Files
26 
27 // TODO: reference additional headers your program requires here
28 
29 //{{AFX_INSERT_LOCATION}}
30 // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
31 
32 #endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
StdAfx.h
  1 #include "stdafx.h"
  2 #include "resourse.h"
  3 
  4 #define MAX_LOADSTRING 100
  5 
  6 // Global Variables:
  7 HINSTANCE hInst;                                // current instance
  8 TCHAR szTitle[MAX_LOADSTRING];                                // The title bar text
  9 TCHAR szWindowClass[MAX_LOADSTRING];                                // The title bar text
 10 HBITMAP bg,dra;
 11 HDC mdc;
 12 
 13 const int xstart=50;
 14 const int ystart=20;
 15 // Foward declarations of functions included in this code module:
 16 ATOM                MyRegisterClass(HINSTANCE hInstance);
 17 BOOL                InitInstance(HINSTANCE, int);
 18 LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
 19 LRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
 20 void                MyPaint(HDC hdc);
 21 //========================================================================================
 22 int APIENTRY WinMain(HINSTANCE hInstance,
 23                      HINSTANCE hPrevInstance,
 24                      LPSTR     lpCmdLine,
 25                      int       nCmdShow)
 26 {
 27      // TODO: Place code here.
 28     MSG msg;
 29 
 30     MyRegisterClass(hInstance);//调用函数向系统注册窗口类别,输入参数hInstance是目前运行程序的对象代码;
 31 
 32     // 调用InitInstance函数,进行初始化操作;
 33     if (!InitInstance (hInstance, nCmdShow))
 34     {
 35         return FALSE;
 36     }
 37 
 38     // 消息循环(通过消息循环来获取信息,
 39     //进行必要的键盘信息转换而后将控制权交给操作系统,
 40     //有操作系统决定哪个程序的消息处理函数处理消息
 41     while (GetMessage(&msg, NULL, 0, 0)) //获取程序消息
 42     {
 43             TranslateMessage(&msg);//转换伪码及字符
 44             DispatchMessage(&msg);//将控制权交给系统,再有系统决定负责处理消息的程序;
 45     }
 46 
 47     return msg.wParam;
 48 }
 49 //=====================================================================================
 50 
 51 
 52 
 53 //=============================================================================================
 54 //在建立程序窗口实体之前,必须先定义一个窗口类别,其中包含所要建立窗口的信息,
 55 //并向系统注册,这里的MyRegisterClass函数就是进行定义及注册窗口类别的函数。
 56 //==============================================================================================
 57 ATOM MyRegisterClass(HINSTANCE hInstance)
 58 {
 59     WNDCLASSEX wcex;            //申请一个窗口类别“WNDCLASSEX”和结构”wcex“
 60                                 //--------------------------------------------------------------
 61                                 //定义vcex结构的各项信息,其中设定信息处理函数(lpfnWndProc)
 62                                 //为WNDPROC,类别名称为(lpszClassName)为”fe";
 63                                 //--------------------------------------------------------------
 64     wcex.cbSize = sizeof(WNDCLASSEX);
 65 
 66     wcex.style            = CS_HREDRAW | CS_VREDRAW;
 67     wcex.lpfnWndProc    = (WNDPROC)WndProc;
 68     wcex.cbClsExtra        = 0;
 69     wcex.cbWndExtra        = 0;
 70     wcex.hInstance        = hInstance;
 71     wcex.hIcon            = NULL;
 72     wcex.hCursor        = NULL;
 73     wcex.hCursor        = LoadCursor(NULL,IDC_ARROW);
 74     wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
 75     wcex.lpszMenuName    = NULL;
 76     wcex.lpszClassName    = "fe";
 77     wcex.hIconSm        = NULL;
 78 
 79     return RegisterClassEx(&wcex);//调用RegisterClassEx函数注册类别,返回一个“ATOM"形态的字符串
 80                                   //此字符串即为类别名称”fe";
 81 }
 82 //============================================================================================
 83 
 84 
 85 //============================================================================================
 86 //按照前面所定义的窗口类别来建立并显示实际的程序窗口
 87 //============================================================================================
 88 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
 89 {
 90    HWND hWnd;
 91    HDC hdc;
 92    hInst = hInstance; // 把instance handle 储存在全局变量中;
 93 
 94    hWnd = CreateWindow("fe","绘图窗口",WS_OVERLAPPEDWINDOW,
 95       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
 96                       //-----------------------------------------------
 97                       //调用CreateWindow函数来建立一个窗口对象
 98                       //第一个参数就是窗口建立依据的类别名称
 99                       //-----------------------------------------------
100    if (!hWnd)
101    {
102       return FALSE;
103    }
104    //------------------------------------------------
105    //设定窗口的位置及窗口的大小,然后绘制显示在设备上
106    //-------------------------------------------------
107    MoveWindow(hWnd,10,10,600,450,true);//位置及大小
108    ShowWindow(hWnd, nCmdShow);//改定窗口显示时的状态
109    UpdateWindow(hWnd);//将窗口绘制在显示设备上
110 
111    hdc=GetDC(hWnd);
112    mdc=CreateCompatibleDC(hdc);
113 
114    BITMAP bm1,bm2;
115    unsigned char *px1,*px2;
116 
117    bg=(HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,600,450,LR_LOADFROMFILE);
118    //名、类型、大小、加载方式;
119    GetObject(bg,sizeof(BITMAP),&bm1);
120 
121    if(bm1.bmBitsPixel!=32 && bm1.bmBitsPixel!=24)
122    {
123        MessageBox(NULL,"此程序只能在 32 bit 或 24 bit 显示模式中运行","警告",0);
124        return FALSE;
125    }
126 
127    px1=new unsigned char[bm1.bmHeight * bm1.bmWidthBytes];
128    GetBitmapBits(bg,bm1.bmHeight*bm1.bmWidthBytes,px1);
129 
130 
131 
132    dra=(HBITMAP)LoadImage(NULL,"dra.bmp",IMAGE_BITMAP,243,120,LR_LOADFROMFILE);
133    GetObject(dra,sizeof(BITMAP),&bm2);
134    px2=new unsigned char[bm2.bmHeight * bm2.bmWidthBytes];
135    GetBitmapBits(dra,bm2.bmHeight*bm2.bmWidthBytes,px2);
136 
137 
138 
139    int xend,yend;
140    int x,y,i;
141    int rgb_b;
142    int PxBytes=bm1.bmBitsPixel/8;
143 
144    xend=xstart+298;
145    yend=ystart+329;
146 
147    for(y=ystart;y<yend;y++)
148    {
149        for(x=xstart;x<xend;x++)
150        {
151            rgb_b=y*bm1.bmWidthBytes+x*PxBytes;
152 
153            px1[rgb_b]=px1[rgb_b]*0.7;
154            px1[rgb_b+1]=px1[rgb_b+1]*0.7;
155            px1[rgb_b+2]=px1[rgb_b+2]*0.7;
156        }
157    }
158 
159 
160    for(y=0;y<(bm2.bmHeight);y++)
161    {
162        for(x=0;x<bm2.bmWidth;x++)
163        {
164            rgb_b=y*bm2.bmWidthBytes+x*PxBytes;
165            i=(ystart+y)*bm1.bmWidthBytes+(xstart+x)*PxBytes;
166 
167            px2[rgb_b]=px2[rgb_b]*0.3+px1[i];
168            px2[rgb_b+1]=px2[rgb_b+1]*0.3+px1[i+1];
169            px2[rgb_b+2]=px2[rgb_b+2]*0.3+px1[i+2];
170        }
171    }
172 
173    SetBitmapBits(dra,bm2.bmHeight*bm2.bmWidthBytes,px2);
174 
175    MyPaint(hdc);
176 
177    ReleaseDC(hWnd,hdc);
178    delete [] px1;
179    delete [] px2;
180 
181    return TRUE;
182 }
183 //============================================================================================
184 
185 
186 //============================================================================================
187 //
188 //============================================================================================
189 void MyPaint(HDC hdc)
190 {
191     SelectObject(mdc,bg);
192     BitBlt(hdc,0,0,1366,768,mdc,0,0,SRCCOPY);//在窗口位置、大小、原图剪切位
193 
194     SelectObject(mdc,dra);
195     BitBlt(hdc,xstart,ystart,121,120,mdc,0,0,SRCCOPY);
196 }
197 //============================================================================================
198 
199 
200 //============================================================================================
201 //在前面定义类别的时候把WndProc定义为消息处理函数(当某些外部消息发生时,会按消息的类型
202 //来决定该如何进行处理。此外该函数也是一个回叫函数(CALLBACK)(windows系统函数)每一个
203 //程序都会接收信息,选择性接受、处理;
204 //============================================================================================
205 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
206 {
207     PAINTSTRUCT ps;
208     HDC hdc;
209 
210     switch (message)                   //判断消息类型
211     {
212         case WM_PAINT:                //窗口重绘制
213             hdc = BeginPaint(hWnd, &ps);
214             MyPaint(hdc);
215             EndPaint(hWnd, &ps);
216             break;
217         case WM_DESTROY:              //处理窗口结束消息
218             DeleteDC(mdc);
219             DeleteObject(bg);
220             PostQuitMessage(0);
221             break;
222         default:
223             return DefWindowProc(hWnd, message, wParam, lParam);
224    }
225    return 0;
226 }
227 //============================================================================================
main.cpp

 

 

posted @ 2014-05-16 21:52  beautifulzzzz  阅读(1189)  评论(1编辑  收藏  举报