--- === Talking about the fade out of the bitmap and the fade out of the graph === ---

zhaozj2021-02-08  208

Talking about the fade out of the chart and fade out

Chengdu University of Electronic Science and Technology

Zhu Ning

In many games and screen saver, we can find the fade out of the bitmap and the appreciation of the fade out of the bitmap (a image gradually disappeared in another image). How to achieve these effects?

In the Windows (GDI) environment, there are three fades of bitmaps, and there are three ways: 1. Palette animation; 2. Mode painting brush; 3. Animation method. Among them, the first method is very fast, but it can only be used for 256 colors of graphics, and it is not easy to achieve the extravagant effect. The second method is relatively simple, but the subjective effect is not as follows. The effect of the third method is very good, but the speed is slightly slow. Since it is now very difficult to get a 256-color picture of quality, in addition, almost all graphics cards support high color and true color mode, it is not recommended to adopt the first method. The following describes the implementation of the two methods in the Visual C programming environment.

1: Picture drawing method:

Bitblt (...), maskblt (...), and win32api :: stretchdibits (...) functions, namely, Pattern Brush And the original graphic of the destination area forms a final output graphic. Therefore, by changing the pattern of the mode painting, some special effects can be formed by a certain ROP operation.

First, you should prepare a plurality of pieces of monochrome bitmaps of 8 * 8, as a template for a mode brush. In the monochrome bitmap, only the pixels of two colors of black and white, the proportion of the two pixels in each bitmap will determine the effect of the display, usually we start with a full black bitmap, gradually increase the proportion of white pixels The last bitmap is made of white pixels.

After these bitmaps are made, they will be imported into the project, named idb_pattern1, idb_pattern2 ... call cbitmap :: loadbitmap (...) function Select it to the corresponding cbitmap object, then call CBRUSH :: CreatePatternbrush (...) Making a model painting brush.

After the right mode painting brush, we also need to set the ROP code we need. For the fade-in operation, the source bitmap is required to be opposite the mode painting brush. For fade out, the bitmap of the current display area and the mode painting brush are required to be in turn. For the projections, we need to brush the in-situ map with the pattern painted, and the results of this result and the bitmap of the current display area and the image of the image (the non-original brush of the original brush) are or. Change the painting in turn, you can get the progressive effect. These operations of the ROP code, there is no corresponding predefined macro in the MFC, but we can calculate it, in the online document "Ternary Raster Operations" of Visual C 5.0, the calculation method is described in detail. In the end we got the fade in, the ROP code of the fade out of operation was 000c0324,0x00a000c9, respectively. The ROP code of the progressive operation is 0x00ac0744. In order to form a complete animation effect, we need to set up a timer to perform this series of operations.

The implementation of the pattern drawing brush method is described below with a simple example.

1: Establish a dialog-based project, named patternemo.

2: Delete "Todo: ..." on the dialog, and add a button, named "Demo"

3: Press New to add the corresponding event handle onDemo (...) for Demo.

4: Add private member variables in CPatternDemo as follows:

CDC * PDC;

CDC MEMDC;

CBITMAP BMP;

Cbrush brush [8];

Uint Counter;

Uint mode;

UINT ONRUN; 5: Use the VC's own bitmap editor, edit 8 * 8 pixels, named the monochrome bitmap, named IDB_Pattern1 ... IDB_Pattern8.

6: IMPORT two 100 * 100 pixels of true color BMP images, named IDB_Bmpsource1 and IDB_Bmpsource2.

7: Adds CPATTERNDEMODLG to CPATTERNDEMODLG to add WM_CREATE message response function oncreate (...), and add the following code:

...

For (int i = 0; i <8; i )

{

Bmp.LoadBitmap (IDB_Pattern1 i);

Brush [i] .createpatternbrush (& BMP);

bmp.deleteObject ();

}

...

8: Add the following code in the cpatterndemodlg :: overdemo (...) function:

...

IF (! onrun)

{

PDC = GetDC ();

PDC-> SetBkcolor (RGB (0, 0, 0));

PDC-> SetTextColor (RGB (255, 255, 255);

PDC-> FillsolidRect (0, 0, 100, 100, RGB (0, 0, 0));

MEMDC.CREATECOMPALEDC (PDC);

Bmp.LoadBitmap (idb_bmpsource1);

MEMDC.SELECTOBJECT (& BMP);

bmp.deleteObject ();

Mode = 1;

COUNTER = 0;

Settimer (1,200, null);

Onrun = 1;

}

...

9: Adds CPATTERNDEMODLG to CPATTERNDEMODLG to add WM_Timer's message response function onTimer (...), and add the following code:

...

IF (Mode == 1)

{

IF (counter> 7)

{

Mode = 2;

COUNTER = 0;

Return;

}

PDC-> SelectObject (& Brush [counter]);

PDC-> Bitblt (0, 0, 100, 100, & MEMDC, 0, 0, 0x000c0324);

Counter ;

}

IF (Mode == 2)

{

IF (counter> 7)

{

Mode = 3;

COUNTER = 0;

Return;

}

IF (counter == 0)

{

Bmp.LoadBitmap (idb_bmpsource2);

MEMDC.SELECTOBJECT (& BMP);

bmp.deleteObject ();

}

PDC-> SelectObject (& Brush [counter]);

PDC-> Bitblt (0, 0, 100, 100, & MEMDC, 0, 0, 0x00AC0744);

Counter ;

}

IF (Mode == 3)

{

IF (counter> 7)

{

MEMDC.DELETEDC ();

bmp.deleteObject ();

Killtimer (1);

Onrun = 0;

Return;

}

PDC-> SelectObject (& Brush [counter]);

PDC-> Bitblt (0, 0, 100, 100, NULL, 0, 0, 0X00A000C9);

Counter ;

}

...

9: Add: in cpatterndemodlg :: cpatternDemodlg ():

...

Onrun = 0;

...

10: Use classwizard to add WM_DESTORY message response functions onDestory (...) for CPatternDemodlg, and add the following code: ...

MEMDC.DELETEDC ();

Killtimer (1);

...

Compiling the project, you can see the first image gradually emerge from the background, then gradually hidden into the second image, then, the second image slowly disappeared in the background in.

Animation:

This method is to implement the data directly operating the bitmap, and the smooth change of the pixel color can be achieved, and the visual effect can be done well, so this approach is very much in the screen.

First, we must understand the structure of the BMP graphics. A BMP graphic consists of two parts, that is, the file header and the data area, the file header stores the size, format, etc. of the BMP graphics, and the data area stores the color information of each pixel of the BMP graphics. For 24-bit true color BMP, the size of the file header is 54 bytes, the first 14 bytes correspond to the BitmapFileInfo structure defined in the VC, and the last 40 bytes correspond to the BitmapInfoHeader structure. We read the data from the BMP data area. After a certain amount of operation, use the Win32API :: StretchDibits (...) function to directly output to the display DC, you can implement some tricks.

Let's step by step to implement a full-screen demo:

1: Generate a dialog-based project, named F1:

2: Delete all the code related to it in f1dlg.h, f1dlg.h, and f1.cpp.

3: Add a base class as Generic CWnd in the project, named CW.

4: Add the following private member variable for 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;

And macro definition in the top of W.H #define BMP_SIZE 192000

5: Add the crete (...) virtual function, WM_CREATE, WM_TIMER, WM_PAINT, WM_DESTORY, WM_LBUTTONDOWN message handle, accept the default function name.

6: Delete the original code in CW :: Create (...), replace 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 the code after #ENDIF in cf1app :: InitInstance (), instead with the following code:

///

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 in 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 in the cw :: overdestroy () function:

Killtimer (1);

GlobalFree (HLB1);

GlobalFree (HLB2);

GlobalFree (HLB3);

/

10: Add the following code in the CW :: Onlbuttondown (...) function:

//

SendMessage (WM_CLOSE);

//

11: Add the following code in the CW: ONLBUTTONDOWN (...) function:

/

CPAINTDC DC (this);

Dc.fillsolidRect (0, 0, 800, 600, RGB (0, 0, 0));

Dc.SetTextColor (RGB (200, 0, 0));

IF (! start) return;

CFILE F1, F2;

F1.Open ("BMP1.BMP", CFile :: ModeRead;

F2.Open ("BMP2.BMP", CFile :: ModeRead;

F1.seek (14, cfile :: begin);

F1.read (& Header, 40);

F2.seek (54, cfile :: begin);

HLB1 = GLOBALLOC (GMEM_MOVEABLE, BMP_SIZE);

P1 = (Byte *) GlobalLock (HLB1);

P1 = (byte *) malloc (bmp_size);

F1.readhuge (P1, BMP_SIZE);

GlobalUnlock (HLB1);

HLB2 = GLOBALLOC (GMEM_MOVEABLE, BMP_SIZE);

P2 = (Byte *) GlobalLock (HLB2);

f2.readhuge (P2, BMP_SIZE);

GlobalUnlock (HLB2);

HLB3 = GLOBALLOC (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 in the CW :: ONTIMER (...) function:

///

IF (stage == 1)

{

IF (Counter > 63)

{

STAGE = 2;

COUNTER = 0;

Return;

}

For (int i = 0; i

P3 [i] = counter * p1 [i] / 64;

:: StretchDibits (getdc () -> m_hdc, x_offset, y_offset, 640, 400, 0, 0, 320, 200, p3,

(BitmapInfo *) (& header), NULL, SRCCOPY;

}

IF (stage == 2)

{

IF (Counter > 63)

{

STAGE = 3;

Counter = 0; Return;

}

For (int i = 0; i

P3 [i] = (64-counter) * p1 [i] / 64 counter * p2 [i] / 64;

:: StretchDibits (getdc () -> m_hdc, x_offset, y_offset, 640, 400, 0, 0, 320, 200, p3,

(BitmapInfo *) (& header), NULL, SRCCOPY;

}

IF (stage == 3)

{

IF (Counter > 63)

{

Killtimer (1);

SendMessage (WM_CLOSE);

Return;

}

For (int i = 0; i

P3 [i] = (64-counter) * p2 [i] / 64;

:: StretchDibits (getdc () -> m_hdc, x_offset, y_offset, 640, 400, 0, 0, 320, 200, p3,

(BitmapInfo *) (& header), NULL, SRCCOPY;

}

//

13: Finally, in the directory where the two resolutions is 320 * 200, named 1.BMP and 2.BMP. Compile the running program, you can see the first in black background. The image (1.BMP) is brighter, and after it completely appears, the second image (2.BMP) is slowly emerging from the first image. When the second image is completely replaced, its brightness gradually decreases, and finally disappears in a black background. Unlike the pattern drawing, these transitions are very smooth.

转载请注明原文地址:https://www.9cbs.com/read-3254.html

New Post(0)