Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Creating a DIB from HANDLE not DDB

Creating a DIB from HANDLE not DDB

Scheduled Pinned Locked Moved C / C++ / MFC
helpgraphicsquestionlearning
4 Posts 2 Posters 6 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Chambers
    wrote on last edited by
    #1

    Hi all, I have a strange (but probably simple) question on DIB's and DDB's. I have a HANDLE (essentially a HBITMAP), and from this I want to create a DIB so that I may access "the bits" etc. Now at the moment, I have the following code, which manages to create a valid HBITMAP (and later on Blits it to the screen - no problem). However, i have had terrible trouble getting access to "the bits" later on in my program, and I think its something to do with the GetDIBitmap function (MSDN says it returns a DDB FROM A DIB). I cannot seem to use the GetObject function either to get a DIBSECTION or BITMAP structure which my program relies on (that is essentially what I need from this, plus the HBITMAP of course). Any help on this would be hugely appreciated (including any better ways of going about converting the HANDLE to a HBITMAP), I have been working on this for days, thats why I haven`t been seen for a while!

    void CMainFrame::GetImage(HANDLE handle)
    {
    CBitmapDoc* pBitmapDoc = NewDocument(); //new doc.
    CBitmapFrame* pBitmapWnd = (CBitmapFrame*)NewWindow(pBitmapDoc);

    BYTE* lpVoid, *pBits;
    LPBITMAPINFO pHead;
    lpVoid = (BYTE*)GlobalLock(handle);
    pHead = (LPBITMAPINFO)lpVoid;
    GlobalUnlock(lpVoid);

    pBits = (BYTE*)lpVoid + sizeof(BITMAPINFOHEADER);

    HBITMAP newbitmap = CreateDIBitmap(pBitmapWnd->GetDC()->m_hDC, &pHead->bmiHeader, CBM_INIT, pBits, pHead, DIB_RGBCOLORS);
    }

    Thanks anyway for looking at my problem, Alan.:confused: "When I left you I was but the learner, now I am the Master" - Darth Vader:mad:

    C 1 Reply Last reply
    0
    • C Chambers

      Hi all, I have a strange (but probably simple) question on DIB's and DDB's. I have a HANDLE (essentially a HBITMAP), and from this I want to create a DIB so that I may access "the bits" etc. Now at the moment, I have the following code, which manages to create a valid HBITMAP (and later on Blits it to the screen - no problem). However, i have had terrible trouble getting access to "the bits" later on in my program, and I think its something to do with the GetDIBitmap function (MSDN says it returns a DDB FROM A DIB). I cannot seem to use the GetObject function either to get a DIBSECTION or BITMAP structure which my program relies on (that is essentially what I need from this, plus the HBITMAP of course). Any help on this would be hugely appreciated (including any better ways of going about converting the HANDLE to a HBITMAP), I have been working on this for days, thats why I haven`t been seen for a while!

      void CMainFrame::GetImage(HANDLE handle)
      {
      CBitmapDoc* pBitmapDoc = NewDocument(); //new doc.
      CBitmapFrame* pBitmapWnd = (CBitmapFrame*)NewWindow(pBitmapDoc);

      BYTE* lpVoid, *pBits;
      LPBITMAPINFO pHead;
      lpVoid = (BYTE*)GlobalLock(handle);
      pHead = (LPBITMAPINFO)lpVoid;
      GlobalUnlock(lpVoid);

      pBits = (BYTE*)lpVoid + sizeof(BITMAPINFOHEADER);

      HBITMAP newbitmap = CreateDIBitmap(pBitmapWnd->GetDC()->m_hDC, &pHead->bmiHeader, CBM_INIT, pBits, pHead, DIB_RGBCOLORS);
      }

      Thanks anyway for looking at my problem, Alan.:confused: "When I left you I was but the learner, now I am the Master" - Darth Vader:mad:

      C Offline
      C Offline
      Chris Losinger
      wrote on last edited by
      #2

      from DDB to DIB, you want GetDIBits. here's how i do it (edit out what you don't want):

      HANDLE CISImgUtil::DDBToDIB( HBITMAP bitmap, UINT32 dwCompression, HPALETTE hPal )
      {

      CCallbackLock lock;
      
      UINT32                   dwLen;
      HANDLE                  hDIB;
      
      ISASSERT( bitmap );
      
      // The function has no arg for bitfields
      if( dwCompression == BI\_BITFIELDS )
      {
      	m\_error=IS\_ERR\_INTERNAL;
      	return NULL;
      }
      
      // If a palette has not been supplied use default palette
      if (hPal==NULL)
      	hPal = (HPALETTE) GetStockObject(DEFAULT\_PALETTE);
      
      BITMAP bm;
      // Get bitmap information
      ::GetObject(bitmap, sizeof(bm),(LPSTR)&bm);
      
      // Initialize the bitmapinfoheader
      BITMAPINFOHEADER        bi;
      bi.biSize               = sizeof(BITMAPINFOHEADER);
      bi.biWidth              = bm.bmWidth;
      bi.biHeight             = bm.bmHeight;
      bi.biPlanes             = 1;
      bi.biBitCount           = bm.bmPlanes \* bm.bmBitsPixel;
      bi.biCompression        = dwCompression;
      bi.biSizeImage          = 0;
      bi.biXPelsPerMeter      = 0;
      bi.biYPelsPerMeter      = 0;
      bi.biClrUsed            = 0;
      bi.biClrImportant       = 0;
      
      // Compute the size of the  infoheader and the color table
      int nColors = (1 << bi.biBitCount);
      
      if( nColors > 256 ) 
      	nColors = 0;
      
      if (bi.biBitCount>31)
      	nColors=0;
      
      dwLen  = bi.biSize + nColors \* sizeof(RGBQUAD);
      
      // We need a device context to get the DIB from
      HDC hDC = GetDC(NULL);
      hPal = SelectPalette(hDC,hPal,FALSE);
      RealizePalette(hDC);
      
      // Allocate enough memory to hold bitmapinfoheader and color table
      hDIB = (HGLOBAL)ISAlloc(dwLen);
      
      if (hDIB==NULL)
      {
      	SelectPalette(hDC,hPal,FALSE);
      	ReleaseDC(NULL,hDC);
      	m\_error=IS\_ERR\_MEM;
      	return NULL;
      }
      
      LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)hDIB;
      
      \*lpbi = bi;
      
      // Call GetDIBits with a NULL lpBits param, so the device driver 
      // will calculate the biSizeImage field 
      if (!GetDIBits(hDC, bitmap, 0L, (UINT32)bi.biHeight,
      	(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (UINT32)DIB\_RGB\_COLORS))
      {
      	// error
      	ISFree(hDIB);
      	
      	// Reselect the original palette
      	SelectPalette(hDC,hPal,FALSE);
      	ReleaseDC(NULL,hDC);
      	
      	m\_error=IS\_ERR\_GETDIB;
      	return NULL;
      }
      
      bi = \*lpbi;
      
      // If the driver did not fill in the biSizeImage field, then compute it
      // Each scan line of the image is aligned on a UINT32 (32bit) boundary
      if (bi.biSizeImage == 0){
      	bi.biSizeImage = ((((bi.biWidth \* bi.biBitCount) + 31) & ~31) / 8) 
      		\* bi.biHeight;
      	
      	// If a com
      
      C 1 Reply Last reply
      0
      • C Chris Losinger

        from DDB to DIB, you want GetDIBits. here's how i do it (edit out what you don't want):

        HANDLE CISImgUtil::DDBToDIB( HBITMAP bitmap, UINT32 dwCompression, HPALETTE hPal )
        {

        CCallbackLock lock;
        
        UINT32                   dwLen;
        HANDLE                  hDIB;
        
        ISASSERT( bitmap );
        
        // The function has no arg for bitfields
        if( dwCompression == BI\_BITFIELDS )
        {
        	m\_error=IS\_ERR\_INTERNAL;
        	return NULL;
        }
        
        // If a palette has not been supplied use default palette
        if (hPal==NULL)
        	hPal = (HPALETTE) GetStockObject(DEFAULT\_PALETTE);
        
        BITMAP bm;
        // Get bitmap information
        ::GetObject(bitmap, sizeof(bm),(LPSTR)&bm);
        
        // Initialize the bitmapinfoheader
        BITMAPINFOHEADER        bi;
        bi.biSize               = sizeof(BITMAPINFOHEADER);
        bi.biWidth              = bm.bmWidth;
        bi.biHeight             = bm.bmHeight;
        bi.biPlanes             = 1;
        bi.biBitCount           = bm.bmPlanes \* bm.bmBitsPixel;
        bi.biCompression        = dwCompression;
        bi.biSizeImage          = 0;
        bi.biXPelsPerMeter      = 0;
        bi.biYPelsPerMeter      = 0;
        bi.biClrUsed            = 0;
        bi.biClrImportant       = 0;
        
        // Compute the size of the  infoheader and the color table
        int nColors = (1 << bi.biBitCount);
        
        if( nColors > 256 ) 
        	nColors = 0;
        
        if (bi.biBitCount>31)
        	nColors=0;
        
        dwLen  = bi.biSize + nColors \* sizeof(RGBQUAD);
        
        // We need a device context to get the DIB from
        HDC hDC = GetDC(NULL);
        hPal = SelectPalette(hDC,hPal,FALSE);
        RealizePalette(hDC);
        
        // Allocate enough memory to hold bitmapinfoheader and color table
        hDIB = (HGLOBAL)ISAlloc(dwLen);
        
        if (hDIB==NULL)
        {
        	SelectPalette(hDC,hPal,FALSE);
        	ReleaseDC(NULL,hDC);
        	m\_error=IS\_ERR\_MEM;
        	return NULL;
        }
        
        LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)hDIB;
        
        \*lpbi = bi;
        
        // Call GetDIBits with a NULL lpBits param, so the device driver 
        // will calculate the biSizeImage field 
        if (!GetDIBits(hDC, bitmap, 0L, (UINT32)bi.biHeight,
        	(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (UINT32)DIB\_RGB\_COLORS))
        {
        	// error
        	ISFree(hDIB);
        	
        	// Reselect the original palette
        	SelectPalette(hDC,hPal,FALSE);
        	ReleaseDC(NULL,hDC);
        	
        	m\_error=IS\_ERR\_GETDIB;
        	return NULL;
        }
        
        bi = \*lpbi;
        
        // If the driver did not fill in the biSizeImage field, then compute it
        // Each scan line of the image is aligned on a UINT32 (32bit) boundary
        if (bi.biSizeImage == 0){
        	bi.biSizeImage = ((((bi.biWidth \* bi.biBitCount) + 31) & ~31) / 8) 
        		\* bi.biHeight;
        	
        	// If a com
        
        C Offline
        C Offline
        Chambers
        wrote on last edited by
        #3

        Geeze, thanks for that Chris, its exactly what i need (minus the palette stuff cos I`m dealing with 24-bit DIBs). I cannot thank you enough for both the detail and accuracy of your response. Many, many thanks, Alan.:-D "When I left you I was but the learner, now I am the Master" - Darth Vader:mad:

        C 1 Reply Last reply
        0
        • C Chambers

          Geeze, thanks for that Chris, its exactly what i need (minus the palette stuff cos I`m dealing with 24-bit DIBs). I cannot thank you enough for both the detail and accuracy of your response. Many, many thanks, Alan.:-D "When I left you I was but the learner, now I am the Master" - Darth Vader:mad:

          C Offline
          C Offline
          Chris Losinger
          wrote on last edited by
          #4

          no problem. actually, that's a chunk of code i got off of codeguru a couple of years ago - it's always worked well for me. just sharing the wealth. -c


          POKE 808,234

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups