eugeneng
asked on
how to use DIB_PAL_COLORS in CreateDIBSection() ?
can anybody tell me how to use DIB_PAL_COLORS in CreateDIBSection ? I've tried lot of times, it just doesn't work.
Below is the code i used to create a DIB bitmap with using DIB_PAL_COLORS
//HWND hWnd - hWnd of window own the bitmap
//RGB_TIGA - rgb struct for palette entries
//HBITMAP hBmp -bmp handle to receive the newly created bmp
BOOL CreateTileBitmap(HWND hWnd,RGB_TIGA pal[4],HBITMAP& hBmp)
{
LPBITMAPINFO lpbi;
lpbi = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEAD ER) +
(COLOR_INDEX * sizeof(RGBQUAD))];
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbi->bmiHeader.biWidth = 8;
lpbi->bmiHeader.biHeight = 8;
lpbi->bmiHeader.biPlanes = 1;
lpbi->bmiHeader.biBitCount = 8;
lpbi->bmiHeader.biCompress ion = BI_RGB;
lpbi->bmiHeader.biSizeImag e = 0;
lpbi->bmiHeader.biXPelsPer Meter = 0;
lpbi->bmiHeader.biYPelsPer Meter = 0;
lpbi->bmiHeader.biClrUsed = 0;
lpbi->bmiHeader.biClrImpor tant = 0;
for (int i=0;i<COLOR_INDEX;i++)
{
lpbi->bmiColors[i].rgbRed = pal[i].bRed<<3;
lpbi->bmiColors[i].rgbGree n = pal[i].bGreen<<3;
lpbi->bmiColors[i].rgbBlue = pal[i].bBlue<<3;
lpbi->bmiColors[i].rgbRese rved =PC_RESERVED;
}
HDC hScreenDC = ::GetDC(hWnd);
hBmp =CreateDIBSection(hScreenD C,lpbi,
DIB_PAL_COLORS,
NULL,NULL,0);
::ReleaseDC(hWnd,hScreenDC );
delete [](BYTE *)lpbi;
return TRUE;
}
is there anything wrong with my code ? is not, then after i've created the bitmap, i use the function below to create a logical palette :
HPALETTE CreatePalette(RGB_TIGA pal[4])
{
HPALETTE hPal;
LOGPALETTE* lpPal =(LOGPALETTE*) new BYTE[sizeof(LOGPALETTE) + (COLOR_INDEX*(sizeof(PALET TEENTRY))) ];
lpPal->palVersion = 0x300;
lpPal->palNumEntries = 4;
for (int i=0;i<COLOR_INDEX;i++)
{
lpPal->palPalEntry[i].peRe d = pal[i].bRed;
lpPal->palPalEntry[i].peGr een = pal[i].bGreen;
lpPal->palPalEntry[i].peBl ue = pal[i].bBlue;
lpPal->palPalEntry[i].peFl ags = PC_RESERVED;
}
hPal = ::CreatePalette(lpPal);
delete [] (BYTE*) lpPal;
return hPal;
}
anything wrong with this ? if no, ok then, now i've created both bitmap and my logical palette, then when i want to
blit the bitmap to the dc, i have to select my desired logical palette into dc right ? is it as below :
HDC dcmem;
CDC *pDC = GetDC();
dcmem = CreateCompatibleDC(pDC->m_ hDC);
HPALETTE oldPal = (HPALETTE) SelectPalette(pDC->m_hDC,& m_hMyPal,F ALSE);
HBITMAP old = (HBITMAP)SelectObject(dcme m,m_hMyBmp );
StretchBlt(pDC->m_hDC,0,0, 8,8,
dcmem,0,0,8,8,SRCCOPY);
SelectPalette(pDC->m_hDC,& oldPal,FAL SE);
SelectObject(dcmem,old);
::DeleteDC(dcmem);
ReleaseDC(pDC);
...anything wrong with these, why the bmp get drawn in blank ? did i miss out something ? If i use DIB_RGB_COLORS, it
would be fined, but i can't because my application will always change the palette and i can't afford to recreate the
bitmap constantly..
can anybody help please ?
Below is the code i used to create a DIB bitmap with using DIB_PAL_COLORS
//HWND hWnd - hWnd of window own the bitmap
//RGB_TIGA - rgb struct for palette entries
//HBITMAP hBmp -bmp handle to receive the newly created bmp
BOOL CreateTileBitmap(HWND hWnd,RGB_TIGA pal[4],HBITMAP& hBmp)
{
LPBITMAPINFO lpbi;
lpbi = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEAD
(COLOR_INDEX * sizeof(RGBQUAD))];
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbi->bmiHeader.biWidth = 8;
lpbi->bmiHeader.biHeight = 8;
lpbi->bmiHeader.biPlanes = 1;
lpbi->bmiHeader.biBitCount
lpbi->bmiHeader.biCompress
lpbi->bmiHeader.biSizeImag
lpbi->bmiHeader.biXPelsPer
lpbi->bmiHeader.biYPelsPer
lpbi->bmiHeader.biClrUsed = 0;
lpbi->bmiHeader.biClrImpor
for (int i=0;i<COLOR_INDEX;i++)
{
lpbi->bmiColors[i].rgbRed = pal[i].bRed<<3;
lpbi->bmiColors[i].rgbGree
lpbi->bmiColors[i].rgbBlue
lpbi->bmiColors[i].rgbRese
}
HDC hScreenDC = ::GetDC(hWnd);
hBmp =CreateDIBSection(hScreenD
DIB_PAL_COLORS,
NULL,NULL,0);
::ReleaseDC(hWnd,hScreenDC
delete [](BYTE *)lpbi;
return TRUE;
}
is there anything wrong with my code ? is not, then after i've created the bitmap, i use the function below to create a logical palette :
HPALETTE CreatePalette(RGB_TIGA pal[4])
{
HPALETTE hPal;
LOGPALETTE* lpPal =(LOGPALETTE*) new BYTE[sizeof(LOGPALETTE) + (COLOR_INDEX*(sizeof(PALET
lpPal->palVersion = 0x300;
lpPal->palNumEntries = 4;
for (int i=0;i<COLOR_INDEX;i++)
{
lpPal->palPalEntry[i].peRe
lpPal->palPalEntry[i].peGr
lpPal->palPalEntry[i].peBl
lpPal->palPalEntry[i].peFl
}
hPal = ::CreatePalette(lpPal);
delete [] (BYTE*) lpPal;
return hPal;
}
anything wrong with this ? if no, ok then, now i've created both bitmap and my logical palette, then when i want to
blit the bitmap to the dc, i have to select my desired logical palette into dc right ? is it as below :
HDC dcmem;
CDC *pDC = GetDC();
dcmem = CreateCompatibleDC(pDC->m_
HPALETTE oldPal = (HPALETTE) SelectPalette(pDC->m_hDC,&
HBITMAP old = (HBITMAP)SelectObject(dcme
StretchBlt(pDC->m_hDC,0,0,
dcmem,0,0,8,8,SRCCOPY);
SelectPalette(pDC->m_hDC,&
SelectObject(dcmem,old);
::DeleteDC(dcmem);
ReleaseDC(pDC);
...anything wrong with these, why the bmp get drawn in blank ? did i miss out something ? If i use DIB_RGB_COLORS, it
would be fined, but i can't because my application will always change the palette and i can't afford to recreate the
bitmap constantly..
can anybody help please ?
// Here's my code for loading up the palette and drawing a DIB section. See if it helps you.
// Ignore the CMemDC stuff for now, It's a wonderful little class that will remove your flickering during redraw.
CPaintDC dc(this); // device context for painting
if( m_bmLogo.GetSafeHandle( ) == NULL )
{
HBITMAP hLogoBitmap = (HBITMAP) ::LoadImage( AfxGetInstanceHandle( ), MAKEINTRESOURCE( IDB_CUSTOMS ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
if( hLogoBitmap )
m_bmLogo.Attach( hLogoBitmap );
HBITMAP hBackBitmap = (HBITMAP) ::LoadImage( AfxGetInstanceHandle( ), MAKEINTRESOURCE( IDB_GRAYTXT ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
if( hBackBitmap )
m_bmBackground.Attach( hBackBitmap );
// Create the palette to go with our DIB section
if(( dc.GetDeviceCaps( RASTERCAPS ) & RC_PALETTE ) != 0 )
{
DIBSECTION ds;
m_bmLogo.GetObject( sizeof( DIBSECTION ), &ds );
// m_bmBackground.GetObject( sizeof( DIBSECTION ), &ds );
int nColors;
if( ds.dsBmih.biClrUsed != 0 )
nColors = ds.dsBmih.biClrUsed;
else
nColors = 1 << ds.dsBmih.biBitCount;
// Create a halftone palette if the DIB section contains more than 256 colors
if( nColors > 256 )
m_palLogo.CreateHalftonePa lette( &dc );
// Create a custom palette from the DIB section's color table
else
{
RGBQUAD* pRGB = new RGBQUAD[ nColors ];
CDC memDC;
memDC.CreateCompatibleDC( &dc );
CBitmap* pOldBitmap = memDC.SelectObject( &m_bmLogo );
// CBitmap* pOldBitmap = memDC.SelectObject( &m_bmBackground );
::GetDIBColorTable( memDC.GetSafeHdc( ), 0, nColors, pRGB );
memDC.SelectObject( pOldBitmap );
UINT uiSize = sizeof( LOGPALETTE ) + ( sizeof( PALETTEENTRY ) * ( nColors - 1 ));
LOGPALETTE* pLP = (LOGPALETTE*) new BYTE[ uiSize ];
pLP->palVersion = 0x300;
pLP->palNumEntries = (unsigned short) nColors;
for( int iCurrColor = 0; iCurrColor < nColors; iCurrColor ++ )
{
pLP->palPalEntry[ iCurrColor ].peRed = pRGB[ iCurrColor ].rgbRed;
pLP->palPalEntry[ iCurrColor ].peGreen = pRGB[ iCurrColor ].rgbGreen;
pLP->palPalEntry[ iCurrColor ].peBlue = pRGB[ iCurrColor ].rgbBlue;
pLP->palPalEntry[ iCurrColor ].peFlags = 0;
}
m_palLogo.CreatePalette( pLP );
delete[] pLP;
delete[] pRGB;
}
}
}
// if( m_bPreviewMode == false )
if( true )
{
CMemDC pMemDC( &dc );
// Get the client rectangle
CRect rcClientRect;
GetClientRect( &rcClientRect );
pMemDC.Rectangle( rcClientRect );
// BitBlts the Logo on to the background
if( m_bmLogo.GetSafeHandle( ))
{
// Setup the palette for this bitmap
CPalette* pOldPalette = NULL;
if( m_palLogo.GetSafeHandle( ))
{
pOldPalette = pMemDC.SelectPalette( &m_palLogo, FALSE );
pMemDC.RealizePalette( );
}
// Create our compatible DC
DIBSECTION ds;
CDC memDC;
memDC.CreateCompatibleDC( &pMemDC );
// Draw the background in a layered format
CBitmap* pOldBitmap = NULL;
#if DRAW_BACKGROUND == 1
pOldBitmap = memDC.SelectObject( &m_bmBackground );
CRect rcClientRect;
GetClientRect( &rcClientRect );
m_bmBackground.GetObject( sizeof( DIBSECTION ), &ds );
int cx = ( rcClientRect.Width ( ) / ( ds.dsBm.bmWidth )) + 1;
int cy = ( rcClientRect.Height( ) / ( ds.dsBm.bmHeight )) + 1;
CPoint ptSize( ds.dsBm.bmWidth, ds.dsBm.bmHeight );
memDC.DPtoLP( &ptSize );
CPoint ptOrigin( 0, 0 );
memDC.DPtoLP( &ptOrigin );
for( int iRows = 0; iRows < cx; iRows ++ )
{
for( int iColumns = 0; iColumns < cy; iColumns ++ )
{
int x = ( iRows * ( ds.dsBm.bmWidth ));
int y = ( iColumns * ( ds.dsBm.bmHeight ));
pMemDC.BitBlt( x, y, ptSize.x, ptSize.y, &memDC, ptOrigin.x, ptOrigin.y, SRCCOPY );
}
}
memDC.SelectObject( pOldBitmap );
#endif
// Draw the logo centered on the immge
m_bmLogo.GetObject( sizeof( DIBSECTION ), &ds );
pOldBitmap = memDC.SelectObject( &m_bmLogo );
CPoint ptLogo(( rcClientRect.Width( ) - ds.dsBm.bmWidth ) / 2, ( rcClientRect.Height( ) - ds.dsBm.bmHeight ) / 2 );
pMemDC.BitBlt( ptLogo.x, ptLogo.y, ds.dsBm.bmWidth, ds.dsBm.bmHeight, &memDC, 0, 0, SRCCOPY );
// DrawTransparentBitmap( &pMemDC, &m_bmLogo, ptLogo.x, ptLogo.y, RGB( 255, 255, 255 ));
// Now free up the information and restore the DC
memDC.SelectObject( pOldBitmap );
if( pOldPalette != NULL )
pMemDC.SelectPalette( pOldPalette, FALSE );
}
}
Phillip
// Ignore the CMemDC stuff for now, It's a wonderful little class that will remove your flickering during redraw.
CPaintDC dc(this); // device context for painting
if( m_bmLogo.GetSafeHandle( ) == NULL )
{
HBITMAP hLogoBitmap = (HBITMAP) ::LoadImage( AfxGetInstanceHandle( ), MAKEINTRESOURCE( IDB_CUSTOMS ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
if( hLogoBitmap )
m_bmLogo.Attach( hLogoBitmap );
HBITMAP hBackBitmap = (HBITMAP) ::LoadImage( AfxGetInstanceHandle( ), MAKEINTRESOURCE( IDB_GRAYTXT ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
if( hBackBitmap )
m_bmBackground.Attach( hBackBitmap );
// Create the palette to go with our DIB section
if(( dc.GetDeviceCaps( RASTERCAPS ) & RC_PALETTE ) != 0 )
{
DIBSECTION ds;
m_bmLogo.GetObject( sizeof( DIBSECTION ), &ds );
// m_bmBackground.GetObject( sizeof( DIBSECTION ), &ds );
int nColors;
if( ds.dsBmih.biClrUsed != 0 )
nColors = ds.dsBmih.biClrUsed;
else
nColors = 1 << ds.dsBmih.biBitCount;
// Create a halftone palette if the DIB section contains more than 256 colors
if( nColors > 256 )
m_palLogo.CreateHalftonePa
// Create a custom palette from the DIB section's color table
else
{
RGBQUAD* pRGB = new RGBQUAD[ nColors ];
CDC memDC;
memDC.CreateCompatibleDC( &dc );
CBitmap* pOldBitmap = memDC.SelectObject( &m_bmLogo );
// CBitmap* pOldBitmap = memDC.SelectObject( &m_bmBackground );
::GetDIBColorTable( memDC.GetSafeHdc( ), 0, nColors, pRGB );
memDC.SelectObject( pOldBitmap );
UINT uiSize = sizeof( LOGPALETTE ) + ( sizeof( PALETTEENTRY ) * ( nColors - 1 ));
LOGPALETTE* pLP = (LOGPALETTE*) new BYTE[ uiSize ];
pLP->palVersion = 0x300;
pLP->palNumEntries = (unsigned short) nColors;
for( int iCurrColor = 0; iCurrColor < nColors; iCurrColor ++ )
{
pLP->palPalEntry[ iCurrColor ].peRed = pRGB[ iCurrColor ].rgbRed;
pLP->palPalEntry[ iCurrColor ].peGreen = pRGB[ iCurrColor ].rgbGreen;
pLP->palPalEntry[ iCurrColor ].peBlue = pRGB[ iCurrColor ].rgbBlue;
pLP->palPalEntry[ iCurrColor ].peFlags = 0;
}
m_palLogo.CreatePalette( pLP );
delete[] pLP;
delete[] pRGB;
}
}
}
// if( m_bPreviewMode == false )
if( true )
{
CMemDC pMemDC( &dc );
// Get the client rectangle
CRect rcClientRect;
GetClientRect( &rcClientRect );
pMemDC.Rectangle( rcClientRect );
// BitBlts the Logo on to the background
if( m_bmLogo.GetSafeHandle( ))
{
// Setup the palette for this bitmap
CPalette* pOldPalette = NULL;
if( m_palLogo.GetSafeHandle( ))
{
pOldPalette = pMemDC.SelectPalette( &m_palLogo, FALSE );
pMemDC.RealizePalette( );
}
// Create our compatible DC
DIBSECTION ds;
CDC memDC;
memDC.CreateCompatibleDC( &pMemDC );
// Draw the background in a layered format
CBitmap* pOldBitmap = NULL;
#if DRAW_BACKGROUND == 1
pOldBitmap = memDC.SelectObject( &m_bmBackground );
CRect rcClientRect;
GetClientRect( &rcClientRect );
m_bmBackground.GetObject( sizeof( DIBSECTION ), &ds );
int cx = ( rcClientRect.Width ( ) / ( ds.dsBm.bmWidth )) + 1;
int cy = ( rcClientRect.Height( ) / ( ds.dsBm.bmHeight )) + 1;
CPoint ptSize( ds.dsBm.bmWidth, ds.dsBm.bmHeight );
memDC.DPtoLP( &ptSize );
CPoint ptOrigin( 0, 0 );
memDC.DPtoLP( &ptOrigin );
for( int iRows = 0; iRows < cx; iRows ++ )
{
for( int iColumns = 0; iColumns < cy; iColumns ++ )
{
int x = ( iRows * ( ds.dsBm.bmWidth ));
int y = ( iColumns * ( ds.dsBm.bmHeight ));
pMemDC.BitBlt( x, y, ptSize.x, ptSize.y, &memDC, ptOrigin.x, ptOrigin.y, SRCCOPY );
}
}
memDC.SelectObject( pOldBitmap );
#endif
// Draw the logo centered on the immge
m_bmLogo.GetObject( sizeof( DIBSECTION ), &ds );
pOldBitmap = memDC.SelectObject( &m_bmLogo );
CPoint ptLogo(( rcClientRect.Width( ) - ds.dsBm.bmWidth ) / 2, ( rcClientRect.Height( ) - ds.dsBm.bmHeight ) / 2 );
pMemDC.BitBlt( ptLogo.x, ptLogo.y, ds.dsBm.bmWidth, ds.dsBm.bmHeight, &memDC, 0, 0, SRCCOPY );
// DrawTransparentBitmap( &pMemDC, &m_bmLogo, ptLogo.x, ptLogo.y, RGB( 255, 255, 255 ));
// Now free up the information and restore the DC
memDC.SelectObject( pOldBitmap );
if( pOldPalette != NULL )
pMemDC.SelectPalette( pOldPalette, FALSE );
}
}
Phillip
ASKER
thanx phillip, but your code doesn't help me any thing, I can't use load bitmap to get the hBitmap, instead i have to create it on the fly and have to change their palette frequently, thats why i have to user palette index instead of rgb color, and your code is kind of hard to read. Anyway, thanx for you help.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Ooops, when I mean > 64 I really mean low order 5 bits are zero.
Cheers,
Raymond.
Cheers,
Raymond.
ASKER
i'm really sorry Raymond, actually COLORINDEX is #define constance where i defined it as #define COLORINDEX 4, so there is no difference between COLORINDEX and 4, because i only need 4 colors, and for the <<3 bit, that is my application requirement, because actually i store the color in 5 bits only, so when i want to display the color, i've to shift it back, just ignore it, doesn't matter..
No problem. You had better reject my answer now.
Cheers,
Raymond.
Cheers,
Raymond.
ASKER