Solved

how to use DIB_PAL_COLORS in CreateDIBSection() ?

Posted on 1998-12-02
7
1,774 Views
Last Modified: 2013-11-20
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(BITMAPINFOHEADER)  +
     (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.biCompression = BI_RGB;
lpbi->bmiHeader.biSizeImage = 0;
lpbi->bmiHeader.biXPelsPerMeter = 0;
lpbi->bmiHeader.biYPelsPerMeter = 0;
lpbi->bmiHeader.biClrUsed = 0;
lpbi->bmiHeader.biClrImportant = 0;

for (int i=0;i<COLOR_INDEX;i++)
{
   lpbi->bmiColors[i].rgbRed      = pal[i].bRed<<3;
   lpbi->bmiColors[i].rgbGreen = pal[i].bGreen<<3;
   lpbi->bmiColors[i].rgbBlue      = pal[i].bBlue<<3;
   lpbi->bmiColors[i].rgbReserved =PC_RESERVED;
}

HDC hScreenDC = ::GetDC(hWnd);
hBmp =CreateDIBSection(hScreenDC,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(PALETTEENTRY)))];
    lpPal->palVersion = 0x300;
    lpPal->palNumEntries = 4;
            
    for (int i=0;i<COLOR_INDEX;i++)
    {
      lpPal->palPalEntry[i].peRed      = pal[i].bRed;
      lpPal->palPalEntry[i].peGreen      = pal[i].bGreen;
      lpPal->palPalEntry[i].peBlue      = pal[i].bBlue;
      lpPal->palPalEntry[i].peFlags      = 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,FALSE);
  HBITMAP old = (HBITMAP)SelectObject(dcmem,m_hMyBmp);
  StretchBlt(pDC->m_hDC,0,0,8,8,
           dcmem,0,0,8,8,SRCCOPY);
   SelectPalette(pDC->m_hDC,&oldPal,FALSE);
   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 ?
0
Comment
Question by:eugeneng
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 

Author Comment

by:eugeneng
ID: 1325685
Adjusted points to 200
0
 
LVL 7

Expert Comment

by:psdavis
ID: 1325686
// 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.CreateHalftonePalette( &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

0
 

Author Comment

by:eugeneng
ID: 1325687
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.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Accepted Solution

by:
rwilson032697 earned 200 total points
ID: 1325688
You are setting the number of entries in the LogPalette to 4 when it should be set to COLORINDEX (256 I assume). This will have the effect of really messing up your palette. Set it to COLORINDEX:

     lpPal->palNumEntries = COLORINDEX;

Also, why do you shift left 3 the red, green and blue components of your pal[i] array? If these channels were fairly saturated (ie values > 64) the result would be zero (or no colour for that channel).

Cheers,

Raymond.

0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1325689
Ooops, when I mean > 64 I really mean low order 5 bits are zero.

Cheers,

Raymond.
0
 

Author Comment

by:eugeneng
ID: 1325690
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..
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1325691
No problem. You had better reject my answer now.

Cheers,

Raymond.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
lucky13 challenge 11 158
changeXy challenge 13 93
ASP.NET C# MessageBox.Show Showing a modal dialog box or form when the application ... 2 185
JQuery serialize and unserialize 8 193
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question