📄 fade.c
字号:
//****************************************************************************
// File: fade.c
//
// Purpose: Shows how to perform palette animation on a logical palette to
// fade a bitmap to black. Also shows how to reduce a 256 color
// palette to a 236 color palette.
//
// Development Team:
// Greg Binkerd - Windows Developer Support
//
// Written by Microsoft Windows Developer Support
// Copyright (c) 1995 Microsoft Corporation. All rights reserved.
//****************************************************************************
#include <stdio.h>
#include <windows.h> // required for all Windows applications
#include "fade.h" // specific to this program
#include "dibapi.h" // specific to this program
extern HINSTANCE hInst; // current instance
extern char szAppName[]; // The name of this application
//***********************************************************************
// Function: FadeBitmap
//
// Purpose: Called when the user requests to load and fade a bitmap.
//
// Parameters:
// hWnd == Handle to the main window
//
// Returns: BOOL indicating success or failure
//
// Comments:
//
// History: Date Author Reason
// 5/24/95 GGB Created
//****************************************************************************
BOOL FadeBitmap(HWND hWnd)
{
HDC hdc;
HPALETTE hPalette;
HDIB hDib;
LPSTR lpDib;
RECT rc;
int nPalNumColors;
static PALETTEENTRY pe[256];
int i,j;
static char szFile[256];
if (!(GetFileName (szFile)))
return 0;
hdc = GetDC(hWnd);
if (!(hDib = OpenDIB(szFile)))
{
ReleaseDC(hWnd,hdc);
MessageBox(hWnd,"Invalid Bitmap File",szAppName,MB_OK);
return 0;
}
// Create a 236 colors or less logical palette with PC_RESERVED set
if (!(hPalette = CreateDIBPaletteReserved(hDib,&nPalNumColors)))
{
ReleaseDC(hWnd,hdc);
DestroyDIB(hDib);
MessageBox(hWnd,"8 BPP DIB's or less are only supported",szAppName,MB_OK);
return 0;
}
// Select and realize the palette
SelectPalette(hdc,hPalette,FALSE);
RealizePalette(hdc);
lpDib = GlobalLock(hDib);
SetRect(&rc,0,0,(int)DIBHeight((LPSTR)lpDib),(int)DIBWidth((LPSTR)lpDib));
GlobalUnlock(hDib);
// Display the DIB
PaintDIB (hdc, &rc, hDib, &rc, hPalette);
// Obtain the original entries in the palette and place them in "pe"
GetPaletteEntries(hPalette, 0, nPalNumColors, (LPPALETTEENTRY)&pe);
//Decrement all of the RGB color values in the palette until they are all (0,0,0)
for (i=0; i<256; i++)
{
for (j = 0; j<nPalNumColors; j++)
{
if (pe[j].peRed) pe[j].peRed--;
if (pe[j].peGreen) pe[j].peGreen--;
if (pe[j].peBlue) pe[j].peBlue--;
}
AnimatePalette(hPalette, 0, nPalNumColors, (LPPALETTEENTRY)&pe);
// Delay...
Sleep(3);
}
// Clean up
DeleteObject(hPalette);
DestroyDIB(hDib);
ReleaseDC(hWnd,hdc);
InvalidateRect(hWnd,NULL,TRUE);
}
//***********************************************************************
// Function: CreateDIBPaletteReserved
//
// Purpose: Creates a logical palette for a given DIB. Will ensure that
// the palette is 236 colors or less.
//
// Parameters:
// hDIB == Handle to the DIB
// nPalNumColors == Used to return the number of colors in the palette
//
// Returns: Logical palette for the DIB
//
// Comments: Parts of the code taken from the wincap32 SDK sample
//
// History: Date Author Reason
// 5/24/95 GGB Created
//****************************************************************************
HPALETTE FAR CreateDIBPaletteReserved (HDIB hDIB, int *nPalNumColors)
{
LPLOGPALETTE lpPal; // pointer to a logical palette
HANDLE hLogPal; // handle to a logical palette
HPALETTE hPal = NULL; // handle to a palette
int i, nNumColors; // loop index, number of colors in "revised" color table
LPSTR lpbi; // pointer to packed-DIB
LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0)
LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (OS/2)
BOOL bWinStyleDIB; // flag which signifies whether this is a Win3.0 DIB
/* if handle to DIB is invalid, return NULL */
if (!hDIB)
return NULL;
/* lock DIB memory block and get a pointer to it */
lpbi = GlobalLock(hDIB);
/* get pointer to BITMAPINFO (Win 3.0) */
lpbmi = (LPBITMAPINFO)lpbi;
/* get pointer to BITMAPCOREINFO (OS/2 1.x) */
lpbmc = (LPBITMAPCOREINFO)lpbi;
/* get the number of colors in the DIB */
nNumColors = DIBNumColors(lpbi);
/* is this a Win 3.0 DIB? */
bWinStyleDIB = IS_WIN30_DIB(lpbi);
// If it is a 256 color DIB, then let's find the lost used 236 colors and make a
// palette out of those colors
if (nNumColors == 256)
{
typedef struct _tagBESTCOLORS
{
DWORD dwColorCnt; //Count of how many times a color is used
BOOL bDontUse; //Should we use this color?
} BESTCOLORS;
static BESTCOLORS bc[256];
BYTE dwLeastUsed[20]; // Least used color indices
LPSTR lpBits; // pointer to D.I. bits of a DIB
int nWidth, nHeight, nBytesPerLine, cx, cy;
memset(bc,0,256*sizeof(BESTCOLORS));
// We should only have 236 colors in our logical palette
nNumColors = 236;
lpBits = FindDIBBits(lpbi);
nWidth = DIBWidth(lpbi);
nHeight = DIBHeight(lpbi);
nBytesPerLine = WIDTHBYTES(nWidth*8);
// Traverse through all of the bits in the bitmap and place the color count
// of each color in the BESTCOLORS array
for (cy = 0; cy < nHeight; cy++)
for (cx = 0; cx < nWidth; cx++)
bc[*(LPBYTE)(lpBits+cy*nBytesPerLine+cx)].dwColorCnt++;
// Let's arbitrarily place the first 20 colors in the "Least Used" list.
for (cx=0;cx<20;cx++)
{
bc[cx].bDontUse = TRUE;
dwLeastUsed[cx] = cx;
}
// Now, let's traverse through all of the colors and sort out the 20 least used
for (cx=0;cx<256;cx++)
{
cy = 0;
while ((!(bc[cx].bDontUse)) && cy <20)
{
if (bc[cx].dwColorCnt < bc[dwLeastUsed[cy]].dwColorCnt)
{
bc[dwLeastUsed[cy]].bDontUse = FALSE;
dwLeastUsed[cy] = cx;
bc[cx].bDontUse = TRUE;
}
cy++;
}
}
/* allocate memory block for logical palette */
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) *
nNumColors);
/* if not enough memory, clean up and return NULL */
if (!hLogPal)
{
GlobalUnlock(hDIB);
return NULL;
}
/* lock memory block and get pointer to it */
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
/* set version and number of palette entries */
lpPal->palVersion = 0x300;
lpPal->palNumEntries = nNumColors;
/* store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB)
* into palette
*/
cx = 0;
for (i = 0; i < 256; i++)
{
// Should we use this color?
if (!((bc[i].bDontUse)))
{
if (bWinStyleDIB)
{
lpPal->palPalEntry[cx].peRed = lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[cx].peGreen = lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[cx].peBlue = lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[cx].peFlags = PC_RESERVED;
}
else
{
lpPal->palPalEntry[cx].peRed = lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[cx].peGreen = lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[cx].peBlue = lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[cx].peFlags = PC_RESERVED;
}
cx++;
}
}
/* create the palette and get handle to it */
hPal = CreatePalette(lpPal);
/* if error getting handle to palette, clean up and return NULL */
if (!hPal)
{
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
return NULL;
}
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
}
// Else, let's do it the normal way (from wincap32) but make sure that we are 236 color
// or less.
else if (nNumColors)
{
if (nNumColors > 236)
nNumColors = 236;
/* allocate memory block for logical palette */
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) *
nNumColors);
/* if not enough memory, clean up and return NULL */
if (!hLogPal)
{
GlobalUnlock(hDIB);
return NULL;
}
/* lock memory block and get pointer to it */
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
/* set version and number of palette entries */
lpPal->palVersion = 0x300;
lpPal->palNumEntries = nNumColors;
/* store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB)
* into palette
*/
for (i = 0; i < nNumColors; i++)
{
if (bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = PC_RESERVED;
}
else
{
lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags = PC_RESERVED;
}
}
/* create the palette and get handle to it */
hPal = CreatePalette(lpPal);
/* if error getting handle to palette, clean up and return NULL */
if (!hPal)
{
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
return NULL;
}
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
}
/* clean up */
GlobalUnlock(hDIB);
/* return handle to DIB's palette */
*nPalNumColors = nNumColors;
return hPal;
}
//***********************************************************************
// Function: GetFileName
//
// Purpose: Calls the GetOpenFileName common dialog to allow the user to
// select a bitmap to display
//
// Parameters:
// szFileName == File name of .BMP to siaply
//
// Returns: BOOL indicating success or failure
//
// Comments: Parts of the code taken from the DibView 16 bit SDK sample
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -