灰度图像与彩色图像之间的淡入淡出与指定背景的淡入淡出相比,仅
要将指定的背景色改为经计算得到灰度值,可创建一个灰度调色板加以保存。
关于彩色位图灰度值的求法,前面曾有介绍,这里不再细说。
返回:位图的淡入淡出
具体创建过程请见源程序:
//参数说明:
//hDIB -位图句柄
//xDest -显示位图的左上角x坐标
//yDest -显示位图的左上角y坐标
//nLoops -循环次数
//nDelay -每次循环中的延时
//nFlag -淡入淡出标志 1--淡入 其它--淡出
int nDelay ,int nFlag)
{
CPalette pal;
CPalette *pOldPalette;
PALETTEENTRY pAnimate[256];
PALETTEENTRY pGray[256];
PALETTEENTRY pOriginal[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;
LPVOID lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && nColors <= 256 )
{
HPALETTE hPal = Create236Palette(hDIB);
pal.Attach( hPal );
//得到位图调色板
pal.GetPaletteEntries(0, nReservedColors, (LPPALETTEENTRY)&pOriginal);
for( int i=0; i < nReservedColors; i++)
{//得到颜色对应灰度值
int nGray = (pOriginal[i].peRed*299+ pOriginal[i].peGreen*587+ pOriginal[i].peBlue*114)/1000;
pGray[i].peRed = nGray;
pGray[i].peGreen = nGray;
pGray[i].peBlue = nGray;
pGray[i].peFlags=PC_RESERVED;
}
pOldPalette = pDC->SelectPalette(&pal, FALSE);
pDC->RealizePalette();
CDC memDC;
memDC.CreateCompatibleDC( pDC );
CBitmap bmp;
bmp.CreateCompatibleBitmap( pDC, nWidth, nHeight );
CBitmap *pOldBitmap = memDC.SelectObject( &bmp );
CPalette *pOldMemPalette = memDC.SelectPalette(&pal, FALSE);
memDC.RealizePalette();
::SetDIBitsToDevice(memDC.m_hDC, 0, 0, nWidth, nHeight, 0, 0, 0,
nHeight, lpDIBBits, (LPBITMAPINFO)hDIB, DIB_RGB_COLORS);
if(nFlag==1)//设置灰度调色板
AnimatePalette(hPal, 0, nColors, (LPPALETTEENTRY)&pGray);
pDC->BitBlt(xDest, yDest, nWidth, nHeight, &memDC,0,0,SRCCOPY );
//设置动态调色板初始值为当前调色板
pal.GetPaletteEntries(0, nColors, (LPPALETTEENTRY)&pAnimate);
memDC.SelectPalette(pOldMemPalette, FALSE);
memDC.SelectObject( pOldBitmap );
//淡入淡出
for( i=1; i <= nLoops; i++ )
{
for (int j = 0; j< nColors; j++)
{
if(nFlag==1)
{
pAnimate[j].peRed = pGray[j].peRed - ((pGray[j].peRed -pOriginal[j].peRed)*i)/nLoops;
pAnimate[j].peGreen = pGray[j].peGreen - ((pGray[j].peGreen-pOriginal[j].peGreen)*i)/nLoops;
pAnimate[j].peBlue = pGray[j].peBlue - ((pGray[j].peBlue -pOriginal[j].peBlue)*i)/nLoops;
pAnimate[j].peFlags = pGray[j].peFlags;
}
else
{
pAnimate[j].peRed = pOriginal[j].peRed -((pOriginal[j].peRed -pGray[j].peRed)*i)/nLoops;
pAnimate[j].peGreen = pOriginal[j].peGreen - ((pOriginal[j].peGreen-pGray[j].peGreen)*i)/nLoops;
pAnimate[j].peBlue = pOriginal[j].peBlue - ((pOriginal[j].peBlue -pGray[j].peBlue)*i)/nLoops;
pAnimate[j].peFlags = pOriginal[j].peFlags;
}
}
pal.AnimatePalette(0, nColors, (LPPALETTEENTRY)&pAnimate);
// Delay...
Sleep(nDelay);
}
pDC->SelectPalette(pOldPalette, FALSE);
}
else if( (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) == 0 && nColors <= 256 )
{
for( int i=0; i < nColors; i++)
{
pOriginal[i].peRed = bmInfo.bmiColors[i].rgbRed ;
pOriginal[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pOriginal[i].peBlue = bmInfo.bmiColors[i].rgbBlue ;
int nGray = (bmInfo.bmiColors[i].rgbRed*299+ bmInfo.bmiColors[i].rgbGreen*587+ bmInfo.bmiColors[i].rgbBlue*114)/1000;
if(nFlag==1)
{
bmInfo.bmiColors[i].rgbRed = nGray;
bmInfo.bmiColors[i].rgbGreen = nGray;
bmInfo.bmiColors[i].rgbBlue = nGray;
}
pGray[i].peRed = nGray;
pGray[i].peGreen = nGray;
pGray[i].peBlue = nGray;
}
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
nHeight, lpDIBBits, (LPBITMAPINFO)hDIB, DIB_RGB_COLORS);
//淡入淡出
for( i=1; i <= nLoops; i++ )
{
for (int j = 0; j< nColors; j++)
{
if(nFlag==1)
{
bmInfo.bmiColors[j].rgbRed = pGray[j].peRed - ((pGray[j].peRed -pOriginal[j].peRed)*i)/nLoops;
bmInfo.bmiColors[j].rgbGreen = pGray[j].peGreen - ((pGray[j].peGreen-pOriginal[j].peGreen)*i)/nLoops;
bmInfo.bmiColors[j].rgbBlue = pGray[j].peBlue - ((pGray[j].peBlue -pOriginal[j].peBlue)*i)/nLoops;
}
else
{
bmInfo.bmiColors[j].rgbRed = pOriginal[j].peRed - ((pOriginal[j].peRed -pGray[j].peRed)*i)/nLoops;
bmInfo.bmiColors[j].rgbGreen = pOriginal[j].peGreen - ((pOriginal[j].peGreen-pGray[j].peGreen)*i)/nLoops;
bmInfo.bmiColors[j].rgbBlue = pOriginal[j].peBlue - ((pOriginal[j].peBlue -pGray[j].peBlue)*i)/nLoops;
}
}
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0, nHeight, lpDIBBits, (LPBITMAPINFO)hDIB, DIB_RGB_COLORS);
// Delay...
Sleep(nDelay);
}
}
else
{
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0, nHeight, lpDIBBits, (LPBITMAPINFO)hDIB, DIB_RGB_COLORS);
}
}