Author: Zhou Long
Abstract image of the abstract image is widely used with image processing and multimedia entertainment software. This article is based on Windows-based palette animation and time code technology designed universal image progressive and infinite algorithms, and implements its Visual C program encoding.
Key words are getting promoted, gradually hidden, palette, palette animation, time code
The image of the image is very important image effect, widely used in image processing and multimedia entertainment software. The greatest difficulties for the design of the gradual / infinite algorithm are speed control, including the color of each pixel in the image, and quickly change the image. If a normal full-graph scanning algorithm is used, the speed is slow, it is difficult to really reflect the progressive / extravagant effect.
Use Windows (3.x.95 / 98 / NT) operating system Special palette management and time code timing mechanism to design a valid image gradient / infinite algorithm. Windows provides a color processing technology called a palette animation (Palette Animation), which changes the color can simulate color in the entries selected in the color palette in the color palette. Set the time code, scheduled to call the technology to get the image color gradient to achieve the graphics and gradualness of the image.
First, palette animation
Implementing a palette animation in Visual C depends on several member functions in the CPAlette class and CDC classes provided by the MFC class library, the basic steps are as follows:
Call the CPALETTE :: CreatePalette (LPLOGPALETTE LPLOGPALETTTE) Function Create a logical palette, pay attention to set the PEFLAGS domain of each color entry structure pointed to by the parameter LPLOGPALETTE to PC_RESERVED to prevent other windows from matching the color with the palette. ;
Call the CDC :: SelectPalette and CDC :: REALIZEPALETTE function Select and implement the logical palette created;
Call the cpalette :: AnimatePalette function to change the color, implement palette animation;
The system palette should be restored after the animation is completed.
CPALETTE :: AnimatePalette is the most critical function, whose prototype is as follows:
Void AnimatePalette
Uint nstartIndex, // started entry number
UINT NNUMENTRIES, / / Variation number
LPPALETTEENTRY LPPALETTECOLORS); / / Logical palette table pointer
LPPALETTECOLORS is a pointer to the PaletteEntry structure, where the color information of the logical palette will be updated. The PaletteEntry structure is defined as follows:
Typedef struct tagpaletteentry {// pe
BYTE PERED;
Byte pegreen;
Byte peblue;
Byte peflags;
} Paletteentry;
Pered, pegreen, peblue represents R, G, and B color component values of logical palette items, respectively. PEFLAGS should be set to PC_RESERVED.
NStartIndex will change the starting table item number in LPPALETTECOLORS, nNumentries will change the number of items in LPPALETTECOLORS.
Second, time code
The CWnd :: SetTimer function can set a system time code and specify that every time time interval makes a Windows system send a WM_TIMER message to the message queue of the window. The window performs timing processing whenever a corresponding WM_TIMER message is received.
WM_TIMER messages should usually be accepted and processed in the window's message loop so that universal timing operations will be made. The generic timing operation should be packaged in a function without entangling with other code. The trick to implement this technology is that the window message is cut in the loop operation. If the message is the specified time code message, the timing process is performed; otherwise the message is distributed to the window message processing mechanism. If the timing operation is over, modify the loop flag and exit the loop. The specific code is as follows: ..................................
/ / Set the time code, PWnd is a window object pointer for processing timing operations
PWND-> SetTimer (0x100, utimeout, null);
// Shield the mouse operation, make the timing operation unaffected
PWND-> setCapture ();
// Start timing operation
Bool bdone = false;
MSG msg;
While (! bdone)
{
IF (: PeekMessage (& MSG, NULL, 0, 0, PM_REMOVE))
{
IF (msg.message == wm_timer && msg. wparam == 0x100)
{
......................
Timed operation code
......................
// Set the loop flag and end the operation as timing operation.
IF (Timed Operation)
BDONE = TRUE;
}
:: TranslateMessage (& MSG);
:: DispatchMessage (& MSG);
}
}
// Release mouse
:: ReleaseCapture ();
// Delete time code
PWND-> KillTimer (0x100);
.............................. .. ..
Function PeekMessage Intercept window message, TranslateMessage and DispatchMessage function interprets and distribute all messages except for specifying the time code message to avoid loss messages.
Third, gradually
As gradually, the process of gradually changing the color from black (RGB (0, 0, 0)) into the color of each pixel. Call the cpalette :: getPaletteenTries function Save the logical table item of the image palette, then call the cpalette :: setPaletteEnTries function Pred, Pegreen, peblue in each logical entry in the logical palette 0, timing call CPALETTE :: AnimatePalette, each time the Pred, Pegreen, peblue value of each logical entry adds a variation until they are equal to the Pred, Pegreen, peblue values of each logical entry in the image logical palette.
The following function fadein is set to 0 by setting each color component value in the palette color entries, and then increment, until all color values are restored into the original color value in the original palette.
// Image as progressively
// Parameter:
// pwnd - window display image
// ppal - Pattern pointer
// ndeta - reduce amount of each color component
// utimeout - time change amount
Void Fadein (CWND * PWND, CPALETTE * PPAL, INT NDETA, UINT UTIMEOUT)
{
/ / Retain the original palette color entries
INT NTOTALCOLORS = PPAL-> getentrycount ();
Paletteentry Palettecolors0 [256];
PPAL-> getPaletteentries (0, NTOTALCOLORS, PALETTECOLORS0);
// First set the color components in the palette table to 0
Paletteentry Palettecolors1 [256];
For (INT i = 0; i Palettecolors1 [i] .pered = 0; Palettecolors1 [i] .pegreen = 0; Palettecolors1 [i] .peblue = 0; Palettecolors1 [i] .peflags = pc_reserved; } PPAL-> setPaletteentries (0, NTOTALCOLORS, PALETTECOLORS1); PPAL-> AnimatePalette (0, NTOTALCOLORS, PALETTECOLORS1); // Set the time code PWND-> SetTimer (0x100, utimeout, null); // begins PWND-> setCapture (); Bool bdone = false; MSG msg; While (! bdone) { IF (: PeekMessage (& MSG, NULL, 0, 0, PM_REMOVE)) { IF (msg.message == wm_timer && msg.wparam == 0x100) { CClientDC DC (PWND); CPALETTE * POLDPAL = DC.SelectPalette (PPAL, FALSE); Dc.RealizePalette (); // increment each color component Paletteentry Palettecolors [256]; PPAL-> GetPaletteentries (0, NTOTALCOLORS, PALETTECOLORS); Bool breed = false; Bool bgreenzero = false; Bool bbluezero = false; For (INT i = 0; i { IF (Palettecolors [i] .pered Ndeta < Palettecolors0 [i] .pered) { Palettecolors [i] .pled = ndeta; Bredzero = false; } Else IF (Palettecolors [i] .pered 1 < Palettecolors0 [i] .pered) { Palettecolors [i] .pered ; Bredzero = false; } Else Bredzero = True; IF (Palettecolors [i] .pegreen NDETA < Palettecolors0 [i] .pegreen) { Palettecolors [i] .pegreen = ndeta; BGreenzero = false; } Else IF (Palettecolors [i] .pegreen 1 < Palettecolors0 [i] .pegreen) { Palettecolors [i] .pegreen ; BGreenzero = false; } Else Bgreenzero = true; IF (Palettecolors [i] .peblue ndeta < Palettecolors0 [i] .peblue) { Palettecolors [i] .peblue = ndeta; BBLUEZERO = FALSE; } Else IF (Palettecolors [i] .peblue 1 { Palettecolors [i] .peblue ; BBLUEZERO = FALSE; } Else BBLUEZERO = TRUE; } / / Until the end of the original value BDONE = Bredzero && Bgreenzero && Bbluezero; / / Make the system change the palette PPAL-> AnimatePalette (0, NTOTALCOLORS, PALETTECOLORS); } :: TranslateMessage (& MSG); :: DispatchMessage (& MSG); } } :: ReleaseCapture (); PWND-> KillTimer (0x100); // Restore the original palette PPAL-> SetPaletteentries (0, NTOTALCOLORS, PALETTECOLORS0); PPAL-> AnimatePalette (0, NTOTALCOLORS, PALETTECOLORS0); } Fourth, gradually The process of gradually changing the color of each pixel of the image into black (RGB (0, 0, 0)), that is called CPALETTE :: AnimatePalette, each time the Pred, Pegreen The PEBLUE value reduces a variation until they are 0. The following function fadeout is decremented by each color component value in the color set of the palette, until all color values become 0 (ie, black) to achieve a gradual impact. // Image getting angry // Parameter: // pwnd - window display image // ppal - Pattern pointer // ndeta - reduce amount of each color component // utimeout - time change amount Void Fadeout (CWND * PWND, CPALETTE * PPAL, INT NDETA, UINT UTIMEOUT) { / / Retain the original palette color entries INT NTOTALCOLORS = PPAL-> getentrycount (); Paletteentry Palettecolors0 [256]; PPAL-> getPaletteentries (0, NTOTALCOLORS, PALETTECOLORS0); // Set the time code PWND-> SetTimer (0x100, utimeout, null); // Beginning PWND-> setCapture (); Bool bdone = false; MSG msg; While (! bdone) { IF (: PeekMessage (& MSG, NULL, 0, 0, PM_REMOVE)) { IF (msg.message == wm_timer && msg.wparam == 0x100) { CClientDC DC (PWND); CPALETTE * POLDPAL = DC.SelectPalette (PPAL, FALSE); Dc.RealizePalette (); Paletteentry Palettecolors [256]; PPAL-> GetPaletteentries (0, NTOTALCOLORS, PALETTECOLORS); Bool breed = false; Bool bgreenzero = false; Bool bbluezero = false; // Decrease color components For (INT i = 0; i IF (Palettecolors [i] .pled> NDETA) { Palettecolors [i] .pered - = ndeta; Bredzero = false; } Else IF (Palettecolors [i] .pered> 1) { Palettecolors [i] .pered - Bredzero = false; } Else Bredzero = True; IF (Palettecolors [i] .pegreen> ndeta) { Palettecolors [i] .pegreen - = ndeta; BGreenzero = false; } Else IF (Palettecolors [i] .pegreen> 1) { Palettecolors [i] .pegreen -; BGreenzero = false; } Else Bgreenzero = true; IF (Palettecolors [i] .peblue> ndeta) { Palettecolors [i] .peblue - = ndeta; BBLUEZERO = FALSE; } Else IF (Palettecolors [i] .peblue> 1) { Palettecolors [i] .peblue--; BBLUEZERO = FALSE; } Else BBLUEZERO = TRUE; } // If all color components are 0, the end is getting BDONE = Bredzero && Bgreenzero && Bbluezero; / / Make the system change the palette PPAL-> AnimatePalette (0, NTOTALCOLORS, PALETTECOLORS); } :: TranslateMessage (& MSG); :: DispatchMessage (& MSG); } } :: ReleaseCapture (); PWND-> KillTimer (0x100); // Restore the original palette PPAL-> SetPaletteentries (0, NTOTALCOLORS, PALETTECOLORS0); PPAL-> AnimatePalette (0, NTOTALCOLORS, PALETTECOLORS0); }