EQuestionAnswers.com Computer/Electronics Questions and Answers
C, C++, VC++, COM/DCOM, DLL and more
#Login #Sign up  Facebook Twitter TGoogle+
 

#Previous question #Index of VC++/WIN32/MFC Questions #Next question

Palette

Palette is a collection of colors in a plate which painter uses to draw a picture. Painter takes differrent colors from each palette entries and draw the picture. Palette is like like a look up table.

Palette in VGA graphics

Graphics card in VGA 2,8,16, 256 color mode works in the same way. It contains a harware palette and stores all possible colors in true color. Hareware uses this look up table to map the true color in the output monitor.

Palette in Bitmaps and GIFs

GIF and bitmaps images still uses these palette mathod. Palette entry colors are stored in the header section and body part is the array of index pixels. 16 color bitmap can hold two pixel information in one byte. 256 color bitmap can store one pixel information in one byte. 16 color bitmap can reduce the size of the image by 1:6 and 256 color bitmap can reduce by 1:3. These GIF and bitmaps does not require any encoder or decoder like JPEG format and still can achieve less size.

PALETTEENTRY

Palette will have an array of color entries. Each palette entry is a color and represented by PALETTEENTRY structure. and it is represented by RGB member.

typedef struct tagPALETTEENTRY {
    BYTE        peRed;
    BYTE        peGreen;
    BYTE        peBlue;
    BYTE        peFlags;
} PALETTEENTRY, *PPALETTEENTRY, FAR *LPPALETTEENTRY;

LOGPALETTE

Logical palette is an array of PALETTEENTRY colors and an member variable to hold the number of entries and version information. This datastructure is used in CreatePalette() function to create a handle to palette.

typedef struct tagLOGPALETTE {
  WORD         palVersion;
  WORD         palNumEntries;
  PALETTEENTRY palPalEntry[1];
} LOGPALETTE;

CreatePalette

CreatePalette API is used to create a palette handle from a logical palette entry. The returned palette handle can be used to SelectPalette() call for selecting new palette to a device context.

HPALETTE CreatePalette(
  _In_ const LOGPALETTE *lplgpl
);

SelectPalette

SelectPalette associates a logical palette handle to a device context.

HPALETTE SelectPalette(
  _In_ HDC      hdc,
  _In_ HPALETTE hpal,
  _In_ BOOL     bForceBackground
);

RealizePalette

The RealizePalette function maps palette entries from the current logical palette to the system palette.

UINT RealizePalette(
  _In_ HDC hdc
);

GetDeviceCaps

GetDeviceCaps() returns one of the associated capabilities of device cotext given by input index. To know if the device context supports palette based color, RASTERCAPS index can be passed and RC_PALETTE bit can checked.

int GetDeviceCaps(
  _In_ HDC hdc,
  _In_ int nIndex
);

Palette Demo

We have a bitmap saved as 16 color format in paint brush

We are using CreatePalette, SelectPalette and RealizePalette in this demo.

/* Button event for drawing a 16/256 color bitmap*/
void CPaletteBmpDlg::OnPaintImageClick() 
{
	CPalette pal;
	HANDLE hBitmap = LoadImage(NULL,
								"C:\\logo.bmp",
								IMAGE_BITMAP,
								0,
								0,
								LR_LOADFROMFILE|LR_DEFAULTSIZE);
	CBitmap bmp;
	bmp.m_hObject = hBitmap;
	LoadBMPPalette("C:\\logo.bmp", &pal);
	DrawBitmap(GetDC(), bmp, &pal);

}

/* Load and Create palette from a 2/4/8/16/256 color bitmap*/
BOOL LoadBMPPalette( LPCTSTR sBMPFile, CPalette *pPal )
{
	CFile file;
	if( !file.Open( sBMPFile, CFile::modeRead) )
		return FALSE;
 
	BITMAPFILEHEADER bmfHeader;
 
	// Read file header
	if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
		return FALSE;
 
	// File type should be 'BM'
	if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
		return FALSE;
 
	// Get length of the remainder of the file and allocate memory
	DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER);
	HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
	if (hDIB == 0)
		return FALSE;
 
	// Read the remainder of the bitmap file.
	if (file.ReadHuge((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen )
	{
		::GlobalFree(hDIB);
		return FALSE;
	}
 
 
	BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
	BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
 
	// If bmiHeader.biClrUsed is zero we have to infer the number
	// of colors from the number of bits used to specify it.
	int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed : 
						1 << bmiHeader.biBitCount;
 
	LPVOID lpDIBBits;
	if( bmInfo.bmiHeader.biBitCount > 8 )
		lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) + 
			((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
	else
		lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
 
	// Create the logical palette
	if( pPal != NULL )
	{
		// Create the palette
		if( nColors <= 256 )
		{
			UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
			LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
 
			pLP->palVersion = 0x300;
			pLP->palNumEntries = nColors;
 
			for( int i=0; i < nColors; i++)
			{
				pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
				pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
				pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
				pLP->palPalEntry[i].peFlags = 0;
			}
 
			pPal->CreatePalette( pLP );
 
			delete[] pLP;
		}
	}

	::GlobalFree(hDIB);
	return TRUE;
}
/* Draw bitmap using BitBlt */
void DrawBitmap(CDC* pDC, CBitmap& bitmap, CPalette *pPal )
{
	// Create a compatible memory DC
	CDC memDC;
	memDC.CreateCompatibleDC( pDC );
	memDC.SelectObject( &bitmap );
 
	// Select and realize the palette if DC supports Palette
	if( pPal != NULL && pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
	{
		pDC->SelectPalette( pPal, FALSE );
		pDC->RealizePalette();
	}
 
	BITMAP bm;
	bitmap.GetBitmap( &bm );
 
	pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0,SRCCOPY);
}

You have viewed 1 page out of 109. Your VC++ learning is 0.00% complete. Login to check your learning progress.

 Vote 0

Similar topics related to this section

#Programming Windows, Fifth Edition (Developer Reference)
#Programming Applications for Microsoft Windows (Microsoft Programming Series)
#Programming Windows with MFC, Second Edition
#Visual C++ Programming
#Programming Microsoft Visual C++, Fifth Edition

* #1 webmaster Sat 26 Apr/2014 10:21:29(GMT)  Like 0 Unlike 0

Dear Users,

We are pleased to inform you that a forum/blog has been incorporated with www.mybestnotes.co.in. You are welcomed to add your comments, requests, codes, solutions and feedback to it. Please login(if already a member) or signup(for free) to avail to this facility.

Regards,
Webmaster

Your message goes here:

Name:Guest
Email:anonymous@unknown.com
My Post:*
Secutiry Code: ******  *
Preview this compose before posting this in discussion forum.
 
Note:
  1. Use [Sxx] code to show smiles. Example [S02]
  2. Use [URL ], example [URL http://www.google.com/]
  3. To display code or un formatted text use [CODE] [/CODE]. Example: [CODE] printf("Hello world"); [/CODE]
 [S01]   [S02]   [S03]   [S04]   [S05]   [S06]   [S07]   [S08] 
 [S09]   [S10]   [S11]   [S12]   [S13]   [S14]   [S15]   [S16] 
 [S17]   [S18]   [S19]   [S20]   [S21]   [S22]   [S23]   [S24] 

Note: Only members are allowed, * fields are mandatory.