• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 845
  • Last Modified:

DC to Dib!

I've got a CDC saving to a dib... BUT only in 2 colors! Screen is setup to use 24bit colour.

Here are the relevant functions:

void CGenerator::RenderFrame(int nChar, CScriptEntry *pEntry)
{
  CDC memDC;
  memDC.CreateCompatibleDC(NULL);

  CBitmap       bitmap;
  bitmap.CreateCompatibleBitmap(&memDC, pEntry->m_nDibWidth,pEntry->m_nDibHeight );

  CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);

  CDIB* pDib = pEntry->GetDibPointer();
  int nRet = pDib->BitBlt(  memDC.m_hDC, 0, 0, pEntry->m_nDibWidth, pEntry->m_nDibHeight, 0, 0);
  pEntry->DisplayText(&memDC, CPoint(0,0), false, nChar);

  CPalette* pPal = memDC.GetCurrentPalette();

  WriteCDCToDIB("C:\\Test.bmp", &memDC);

  memDC.SelectObject(pOldBitmap);
}


BOOL CGenerator::WriteCDCToDIB(LPTSTR szFile, CDC *pDC)
{
  CBitmap* pBitmap = pDC->GetCurrentBitmap();
  // Create logical palette if device supports a palette
  CPalette pal;
  if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
  {
    UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
    LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
    pLP->palVersion = 0x300;
    pLP->palNumEntries = GetSystemPaletteEntries( *pDC, 0, 255, pLP->palPalEntry );
    // Create the palette
    pal.CreatePalette( pLP );

    delete[] pLP;
    }
      
    HANDLE hDIB = DDBToDIB( *pBitmap, BI_RGB, &pal );      // Convert the bitmap to a DIB

  if( hDIB == NULL )            return FALSE;

  // Write it to file
  CFile file;
  if (!file.Open(szFile, CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive)) AfxMessageBox("Oh Dear");

  BOOL bSuccess = FALSE;
  bSuccess = ::SaveDIB( (HDIB)hDIB, file);
  file.Close();

  // Free the memory allocated by DDBToDIB for the DIB
  GlobalFree( hDIB );
  return TRUE;
}
0
jhattingh
Asked:
jhattingh
  • 5
  • 3
1 Solution
 
AlexVirochovskyCommented:
I think, it is very easy. Simple you must create Bitmap with 2 colors and
same H, W,copy you Bitmap to
this Bitmap, and save to disk!
Alex
0
 
chensuCommented:
bitmap.CreateCompatibleBitmap(&memDC, pEntry->m_nDibWidth,pEntry->m_nDibHeight );

should be

CDC ScrnDC;
ScrnDC.CreateIC(_T("DISPLAY"), NULL, NULL, NULL);
bitmap.CreateCompatibleBitmap(&ScrnDC, pEntry->m_nDibWidth,pEntry->m_nDibHeight);

This is because a memory DC is 1x1 monochrome when it is initially created.
0
 
jhattinghAuthor Commented:
I'm glad you operate on saturdays!!!!

.... trying it out...

LWJason
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
jhattinghAuthor Commented:
Sorry mate - you misunderstood my question.

0
 
jhattinghAuthor Commented:
Ok here's my new code:

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Function Header
void CGenerator::RenderFrame(int nChar, CScriptEntry *pEntry)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
      CDC memDC;
      CBitmap       bitmap;

      //int nReturn = memDC.CreateCompatibleDC(NULL);
      int nReturn = memDC.CreateIC(_T("DISPLAY"), NULL, NULL, NULL);
      TRACE1("\n\n## Returned a %d\n\n", nReturn);
      
      bitmap.CreateCompatibleBitmap(&memDC, pEntry->m_nDibWidth,pEntry->m_nDibHeight );

      CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);

      CDIB* pDib = pEntry->GetDibPointer();
      int nRet = pDib->BitBlt(  memDC.m_hDC, 0, 0, pEntry->m_nDibWidth, pEntry->m_nDibHeight, 0, 0);
      pEntry->DisplayText(&memDC, CPoint(0,0), false, nChar);

      CPalette* pPal = memDC.GetCurrentPalette();

      WriteCDCToDIB("C:\\Test.bmp", &memDC);

      memDC.SelectObject(pOldBitmap);
}



For some reason, using CreateIC results in an empty bitmap... :(
0
 
chensuCommented:
Sorry mate - you misunderstood my answer.

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Function Header
void CGenerator::RenderFrame(int nChar, CScriptEntry *pEntry)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
CDC memDC, scrnDC;
scrnDC.CreateIC(_T("DISPLAY"), NULL, NULL, NULL);

CBitmap bitmap;

int nReturn = memDC.CreateCompatibleDC(NULL);   // using &scrnDC instead of NULL is also OK
TRACE1("\n\n## Returned a %d\n\n", nReturn);

bitmap.CreateCompatibleBitmap(&scrnDC, pEntry->m_nDibWidth,pEntry->m_nDibHeight );

CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);

CDIB* pDib = pEntry->GetDibPointer();
int nRet = pDib->BitBlt(  memDC.m_hDC, 0, 0, pEntry->m_nDibWidth, pEntry->m_nDibHeight, 0, 0);
pEntry->DisplayText(&memDC, CPoint(0,0), false, nChar);

CPalette* pPal = memDC.GetCurrentPalette();

WriteCDCToDIB("C:\\Test.bmp", &memDC);

memDC.SelectObject(pOldBitmap);
}
0
 
chensuCommented:
If CGenerator is derived from CWnd, you may also use

CClientDC scrnDC(this);

instead of

CDC scrnDC;
scrnDC.CreateIC(_T("DISPLAY"), NULL, NULL, NULL);
0
 
jhattinghAuthor Commented:
Thanks Chens, I'm trying it out...
0
 
jhattinghAuthor Commented:
YEEEEHA!!!
0

Featured Post

Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now