Introduction to bitmap fade-in, fade-out, and bitmap operations

Source: Internet
Author: User
Tags bmp image
In many games and Screen Protection Program , We can all find the application of Bitmap fade-in and fade-out (one image gradually disappears into another image. How can we achieve these results?

In Windows (GDI), there are three ways to fade in and fade out bitmap: 1. palette animation; 2. Pattern Painting Brush; 3. animation. Among them, the first method is fast, but can only be used for 256-color graphics, and it is not easy to achieve the effect of fading. The second method is relatively simple, but the subjective effect is less than the other two methods. The third method works well, but the speed is slower. Because it is difficult to obtain high-quality 256-color images, and currently almost all graphics cards support high-color and true-color models, the first method is not recommended. The following describes the implementation of the last two methods in the Visual C ++ programming environment.

I. Pattern painter method:
Bitblt (...) of the CDC class (...), maskblt (...), and WIN32API: stretchdibits (...) all functions support the raster operation, that is, the final output image is formed by the source, pattern brush, and the original image of the target region through some logic operations. Therefore, some special effects can be formed by changing the pattern of the image and adding a certain amount of drop operation.
First, you need to prepare several 8*8 monochrome bitmaps as the pattern painting template. A monochrome bitmap must contain only black and white pixels. the ratio and shape of the two pixels in each bitmap determine the display effect. Generally, we start with a black bitmap, gradually increase the proportion of white pixels. The last bitmap is composed of white pixels.
After creating these bitmaps, import them into the project and name them idb_pattern1 and idb_pattern2 ...... call cbitmap: loadbitmap (...) the function selects the corresponding cbitmap object and calls cbrush: createpatternbrush (...) create mode painter.
With the appropriate pattern paint brush, we also need to set the desired ROP Code. For the fade-in operation, we need to reverse and reverse the source bitmap and pattern paint brush. For the fade-out operation, the bitmap and Pattern Painting in the current display area must be in sequence. For the gradual hiding, we need to combine the original bitmap with the pattern image, and then combine the result with the bitmap of the current display area and the image of the image painting brush (not the original image painting brush. You can change the painting brush in sequence to get a gradual effect. There is no pre-defined macro in MFC for these operations, but we can obtain it through computation. In the online document "ternary raster operations" in Visual C ++ 5.0, the calculation method is described in detail. In the end, we get the drop-in and fade-out operations with the drop code 000c0324 and 0x00a000c9 respectively. The code for the gradient operation is 0x00ac0744. To form a complete animation effect, we need to set a timer to automatically execute this series of operations.
The following is a simple example to illustrate the implementation of the Pattern Painting method:
1: Create a dialog box-based project named patterndemo.
2: delete the "Todo:..." comment in the dialog box and add a button named "Demo"
3: add the corresponding event handle ondemo (...) to the demo button (...).
4. Add the private member variable in cpatterndemo as follows:
CDC * PDC;
CDC memdc;
Cbitmap BMP;
Cbrush brush [8];
Uint counter;
Uint mode;
Uint onrun;
5: Use the bitmap editor provided by VC to edit 8 8*8 pixels of monochrome bitmap as required above, and name it idb_pattern1..idb_pattern8.
6: import two 100*100 pixel BMP images named idb_bmp source1 and idb_bmp source2.
7: Use classwizard to add the message response function oncreate (...) of wm_create to cpatterndemodlg, and add the following in it: Code :
...

For (INT I = 0; I <8; I ++)
{
BMP. loadbitmap (idb_pattern1 + I );
Brush [I]. createpatternbrush (& BMP );
BMP. deleteobject ();
}
...
8: Add the following code to the cpatterndemodlg: ondemo (...) function:
...
If (! Onrun)
{
PDC = getdc ();
PDC-> setbkcolor (RGB (0, 0, 0 ));
PDC-> settextcolor (RGB (255,255,255 ));
PDC-> fillsolidrect (100,100, RGB (, 0 ));
Memdc. createcompatibledc (PDC );
BMP. loadbitmap (idb_bmp source1 );
Memdc. SelectObject (& BMP );
BMP. deleteobject ();
Mode = 1;
Counter = 0;
Settimer (1,200, null );
Onrun = 1;
}
...
9: Use classwizard to add the message response function ontimer (...) of wm_timer to cpatterndemodlg, and add the following code in it:
...
If (mode = 1)
{
If (counter> 7)
{
Mode = 2;
Counter = 0;
Return;
}
PDC-> SelectObject (& brush [Counter]);
PDC-> bitblt (100,100, & memdc, 0x000c0324 );
Counter ++;
}
If (mode = 2)
{
If (counter> 7)
{
Mode = 3;
Counter = 0;
Return;
}
If (counter = 0)
{
BMP. loadbitmap (idb_bmp source2 );
Memdc. SelectObject (& BMP );
BMP. deleteobject ();
}
PDC-> SelectObject (& brush [Counter]);
PDC-> bitblt (100,100, & memdc, 0x00ac0744 );
Counter ++;
}
If (mode = 3)
{
If (counter> 7)
{
Memdc. deletedc ();
BMP. deleteobject ();
Killtimer (1 );
Onrun = 0;
Return;
}
PDC-> SelectObject (& brush [Counter]);
PDC-> bitblt (100,100, null, 0x00a000c9 );
Counter ++;
}
...
9: add the following to cpatterndemodlg: cpatterndemodlg:
...
Onrun = 0;
...
10: Use classwizard to add the message response function ondestory (...) of wm_destory to cpatterndemodlg, and add the following code to it:
...
Memdc. deletedc ();
Killtimer (1 );
...
Compile and run the project, you can see that the first image gradually emerged from the background, and then gradually moved into the second image, and then, the second image slowly disappeared into the background.

Animation method:
This method is implemented by directly operating the bitmap data, which can achieve smooth changes in pixel color and visual effects. Therefore, this method is widely used in screen saver.
First, we must understand the structure of the BMP image. A bmp image consists of two parts: the file header and data area. The file header stores information such as the size and format of the BMP image, and the color information of each pixel of the BMP image in the data area. For 24-bit real-color BMP, the size of the file header is 54 bytes. the first 14 bytes correspond to the bitmapfileinfo structure defined in VC, And the last 40 bytes correspond to the bitmapinfoheader structure. We read the data in the BMP data area and perform some operations. Then, we can use the WIN32API: stretchdibits (...) function to directly output the data to the display DC to achieve some special effects.
Next let's implement a full-screen demo program step by step:
1: generate a dialog box-based project named F1:
2: delete all codes related to f1dlg. H, f1dlg. H, and f1.cpp.
3: Add a new class named GENERIC cwnd to the project and name it CW.
4: Add the following private member variables to the CW class:
//////////////////////
Uint y_offset;
Uint x_offset;
Uint stage;
Byte * P3;
Byte * P2;
Byte * P1;
Bitmapinfoheader header;
Hglobal hlb1;
Hglobal hlb2;
Hglobal hlb3;
Uint start;
Uint counter;
////////////////////////
Add the macro definition # define BMP _size 192000 to the top of W. H.
5: add the CREATE (...) virtual function, wm_create, wm_timer, wm_paint, wm_destory, wm_lbuttondown message handle for CW, and accept the default function name.
6. Delete the original code in CW: Create (...) and replace it with the following code:
/////////////////////////
Lpctstr m_lpszcn;
M_lpszcn = afxregisterwndclass (cs_bytealignclient,
: Loadcursor (afxgetresourcehandle (),
Makeintresource (idc_nullcorsor )));
Return cwnd: createex (ws_ex_topmost, m_lpszcn, lpszwindowname, dwstyle, rect, pparentwnd, NID, pcontext );
//////////////////////////
7. Delete all codes after # endif in cf1app: initinstance (). Use the following code instead:
///////////////////////////
Int Cx = getsystemmetrics (sm_cxscreen );
Int Cy = getsystemmetrics (sm_cyscreen );
Crect rectdefault (0, 0, CX, CY );
M_pmainwnd = new CW ();
M_pmainwnd-> Create (null, _ T ("Hello world! "), Ws_visible | ws_popup, rectdefault, null, null );
Return true;
///////////////////////////
8: Add the following code to the CW: oncreate (...) function:
/////////////////////////////
Counter = 0;
Int Cx = getsystemmetrics (sm_cxscreen );
Int Cy = getsystemmetrics (sm_cyscreen );
X_offset = (cx-640)/2;
Y_offset = (cy-400)/2;
/////////////////////////////
9: Add the following code to the CW: ondestroy () function:
////////////////////////////////
Killtimer (1 );
Globalfree (hlb1 );
Globalfree (hlb2 );
Globalfree (hlb3 );
/////////////////////////////
10: Add the following code to the CW: onlbuttondown (...) function:
//////////////////////////////
Sendmessage (wm_close );
//////////////////////////////
11: Add the following code to the CW: onlbuttondown (...) function:
/////////////////////////////
Cpaintdc DC (this );
DC. fillsolidrect (800,600, RGB (, 0 ));
DC. settextcolor (RGB (200,0, 0 ));
If (! Start) return;
Cfile F1, F2;
F1.open ("BMP 1.bmp", cfile: moderead );
F2.open ("BMP 2.bmp", cfile: moderead );
F1.seek (14, cfile: Begin );
F1.read (& header, 40 );
F2.seek (54, cfile: Begin );
Hlb1 = globalalloc (gmem_moveable, BMP _size );
P1 = (byte *) globallock (hlb1 );
P1 = (byte *) malloc (BMP _size );
F1.readhuge (P1, BMP _size );
Globalunlock (hlb1 );
Hlb2 = globalalloc (gmem_moveable, BMP _size );
P2 = (byte *) globallock (hlb2 );
F2.readhuge (P2, BMP _size );
Globalunlock (hlb2 );
Hlb3 = globalalloc (gmem_moveable, BMP _size );
P3 = (byte *) globallock (hlb3 );
Globalunlock (hlb3 );
F1.close ();
F2.close ();
Stage = 1;
Settimer (1,100, null );
Start = 0;
///////////////////////////
12: Add the following code to the CW: ontimer (...) function:
///////////////////////////
If (stage = 1)
{
If (counter ++> 63)
{
Stage = 2;
Counter = 0;
Return;
}
For (INT I = 0; I <BMP _size; I ++)
P3 [I] = counter * P1 [I]/64;
: Stretchdibits (getdc ()-> m_hdc, x_offset, y_offset, 640,400, 320,200, P3,
(Bitmapinfo *) (& header), null, srccopy );
}
If (stage = 2)
{
If (counter ++> 63)
{
Stage = 3;
Counter = 0;
Return;
}
For (INT I = 0; I <BMP _size; I ++)
P3 [I] = (64-counter) * P1 [I]/64 + counter * P2 [I]/64;
: Stretchdibits (getdc ()-> m_hdc, x_offset, y_offset, 640,400, 320,200, P3,
(Bitmapinfo *) (& header), null, srccopy );
}
If (stage = 3)
{
If (counter ++> 63)
{
Killtimer (1 );
Sendmessage (wm_close );
Return;
}
For (INT I = 0; I <BMP _size; I ++)
P3 [I] = (64-counter) * P2 [I]/64;
: Stretchdibits (getdc ()-> m_hdc, x_offset, y_offset, 640,400, 320,200, P3,
(Bitmapinfo *) (& header), null, srccopy );
}
//////////////////////////////////
13: At last, two 24bitbmp files with a resolution of 320 * are stored in the project directory, named 1.bmp and 2.bmp. Large) and gradually emerge from the first image. When the second image completely replaces the first image, its brightness gradually decreases and eventually disappears into the black background. Unlike the pattern painter method, the transition is smooth.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.