📄 grayscale_fadein.shtml
字号:
((peGray[j].peBlue -peOriginal[j].peBlue)*i)/nLoops;
}
// Draw the image again
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0,
0, 0, nHeight, lpDIBBits, (LPBITMAPINFO)hDIB,
DIB_RGB_COLORS);
// Delay...
Sleep(nDelay);
}
}
else
{
// Any other scenario, simply draw the image
LPVOID lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
nHeight, lpDIBBits, (LPBITMAPINFO)hDIB, DIB_RGB_COLORS);
}
}
</FONT></TT></PRE>
<h4>Function 2: Fade from color to grayscale</h4>
The FadeColorToGrayScale () draws the device-independent bitmap (DIB) onto the device context as a full color image and then slowly changes it to a grayscale image. Since this function starts by drawing the image with a color palette it doesn't have to worry about two very different colors getting mapped to the same color as can happen if we start with a grayscale palette instead. This, of course, applies only displays that support a palette.
<PRE><TT><FONT COLOR="#990000">
// FadeColorToGrayScale - Draws a bitmap in color slowly turns it to grayscale
// pDC - Pointer to target device context
// hDIB - Handle of device-independent bitmap
// xDest - x-coordinate of upper-left corner of dest. rect.
// yDest - y-coordinate of upper-left corner of dest. rect.
// nLoops - How many loops to fade the image into color
// nDelay - Delay in milli-seconds between each loop
//
void FadeColorToGrayScale( CDC *pDC, HANDLE hDIB, int xDest, int yDest, int nLoops,
int nDelay )
{
CPalette pal;
CPalette *pOldPalette;
PALETTEENTRY peAnimate[256];
PALETTEENTRY peGray[256];
PALETTEENTRY peOriginal[256];
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
1 << bmInfo.bmiHeader.biBitCount;
int nReservedColors = nColors > 236 ? 236 : nReservedColors;
int nWidth = bmInfo.bmiHeader.biWidth;
int nHeight = bmInfo.bmiHeader.biHeight;
// Create the palette if needed
if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && nColors <= 256 )
{
// The device supports a palette and bitmap has color table
HPALETTE hPal = CreateReservedPalette(hDIB);
pal.Attach( hPal );
// Now save the original colors and get the grayscale colors
pal.GetPaletteEntries(0, nReservedColors, (LPPALETTEENTRY)&peOriginal);
for( int i=0; i < nReservedColors; i++)
{
long lSquareSum = peOriginal[i].peRed
* peOriginal[i].peRed
+ peOriginal[i].peGreen
* peOriginal[i].peGreen
+ peOriginal[i].peBlue
* peOriginal[i].peBlue;
int nGray = (int)sqrt(((double)lSquareSum)/3);
peGray[i].peRed = nGray;
peGray[i].peGreen = nGray;
peGray[i].peBlue = nGray;
}
// Select the palette
pOldPalette = pDC->SelectPalette(&pal, FALSE);
pDC->RealizePalette();
// Draw the image
LPVOID lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
nHeight, lpDIBBits, (LPBITMAPINFO)hDIB, DIB_RGB_COLORS);
// Now animate palette to set the image to grayscale
for( i=1; i <= nLoops; i++ )
{
for (int j = 0; j< nColors; j++)
{
peAnimate[j].peRed = peOriginal[j].peRed -
((peOriginal[j].peRed -peGray[j].peRed)*i)/nLoops;
peAnimate[j].peGreen = peOriginal[j].peGreen -
((peOriginal[j].peGreen-peGray[j].peGreen)*i)
/nLoops;
peAnimate[j].peBlue = peOriginal[j].peBlue -
((peOriginal[j].peBlue -peGray[j].peBlue)*i)/nLoops;
peAnimate[j].peFlags = peOriginal[j].peFlags;
}
pal.AnimatePalette(0, nColors, (LPPALETTEENTRY)&peAnimate);
// Delay...
Sleep(nDelay);
}
// Select the old palette back
pDC->SelectPalette(pOldPalette, FALSE);
}
else if( (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) == 0 && nColors <= 256 )
{
// Device does not supports palettes but bitmap has a color table
// Modify the bitmaps color table directly
// Get the original colors and the grayscale colors
for( int i=0; i < nColors; i++)
{
// First save original colors
peOriginal[i].peRed = bmInfo.bmiColors[i].rgbRed ;
peOriginal[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
peOriginal[i].peBlue = bmInfo.bmiColors[i].rgbBlue ;
long lSquareSum = bmInfo.bmiColors[i].rgbRed
* bmInfo.bmiColors[i].rgbRed
+ bmInfo.bmiColors[i].rgbGreen
* bmInfo.bmiColors[i].rgbGreen
+ bmInfo.bmiColors[i].rgbBlue
* bmInfo.bmiColors[i].rgbBlue;
int nGray = (int)sqrt(((double)lSquareSum)/3);
// Create a reference color table
peGray[i].peRed = nGray;
peGray[i].peGreen = nGray;
peGray[i].peBlue = nGray;
}
// Let's draw the color image
LPVOID lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
nHeight, lpDIBBits, (LPBITMAPINFO)hDIB, DIB_RGB_COLORS);
// Now change the image to grayscale
for( i=1; i <= nLoops; i++ )
{
for (int j = 0; j< nColors; j++)
{
bmInfo.bmiColors[j].rgbRed = peOriginal[j].peRed -
((peOriginal[j].peRed -peGray[j].peRed)*i)/nLoops;
bmInfo.bmiColors[j].rgbGreen = peOriginal[j].peGreen -
((peOriginal[j].peGreen-peGray[j].peGreen)*i)/
nLoops;
bmInfo.bmiColors[j].rgbBlue = peOriginal[j].peBlue -
((peOriginal[j].peBlue -peGray[j].peBlue)*i)/nLoops;
}
// Draw the image again
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0,
0, 0, nHeight, lpDIBBits, (LPBITMAPINFO)hDIB,
DIB_RGB_COLORS);
// Delay...
Sleep(nDelay);
}
}
else
{
// Any other scenario, simply draw the image
LPVOID lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
nHeight, lpDIBBits, (LPBITMAPINFO)hDIB, DIB_RGB_COLORS);
}
}
</FONT></TT></PRE>
<P>
<HR>
<TABLE BORDER=0 WIDTH="100%" >
<TR>
<TD WIDTH="33%"><FONT SIZE=-1><A HREF="http://www.codeguru.com">Goto HomePage</A></FONT></TD>
<TD WIDTH="33%">
<CENTER><FONT SIZE=-2>© 1998 Zafir Anjum</FONT> </CENTER>
</TD>
<TD WIDTH="34%">
<DIV ALIGN=right><FONT SIZE=-1>Contact me: <A HREF="mailto:zafir@home.com">zafir@home.com</A> </FONT></DIV>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -