Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

how to use DIB_PAL_COLORS in CreateDIBSection() ?

Posted on 1998-12-02
7
Medium Priority
?
1,895 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 12

Accepted Solution

by:
rwilson032697 earned 400 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
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.
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…

609 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