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. GetDIBits() function call fails

GetDIBits() function call fails

Scheduled Pinned Locked Moved C / C++ / MFC
graphicshelpjsonquestion
3 Posts 3 Posters 0 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.
  • T Offline
    T Offline
    TheDelChop
    wrote on last edited by
    #1

    Anybody see what the problem is with this code? GetDIBits fails, and when I call GetLastError(), it tells me that Windows "ERROR_FILE_NOT_FOUND". GetClientRect(hDlg, &rc); // Get the rectangle dimensions of the Dialog Box hdc = GetDC(hDlg); // Get a handle to the Drawing Context of the Dialog Box rc.bottom -= (GetSystemMetrics(SM_CYHSCROLL)+GetSystemMetrics(SM_CYEDGE)); hSavedXYContext = CreateCompatibleDC(hdc); // Create a drawing context that is compatiable to // the drawing context on the screen hSavedXYBitmap = CreateCompatibleBitmap(hdc, rc.right-rc.left,rc.bottom-rc.top); hTheDCsOriginalBitmap = (HBITMAP)SelectObject(hSavedXYContext, hSavedXYBitmap); BitBlt(hSavedXYContext,0,0,rc.right-rc.left, rc.bottom-rc.top,hdc,0,0,SRCCOPY); hSavedXYBitmap = (HBITMAP)SelectObject(hSavedXYContext, hTheDCsOriginalBitmap); // As far as I can tell above code does exactly what it should. It grabs a handle to the drawing // context, along with the rectangular coordinates of the drawing context. Then after creating // a compatible bitmap, and selecting it into the saved drawing context, before blting it in. // Now we have the DC saved to hSavedContext, so we need to take it and create a // bitmap file that we can open in Paint. // This involves creating a bmp structure then writing it to a file. GetObject(hSavedXYBitmap,sizeof(BITMAP),(LPSTR)(&bmp)); cClrBits = (WORD)(bmp.bmPlanes*bmp.bmBitsPixel); cClrBits = 4; pbmi = (PBITMAPINFO) LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)); // Initialize the fields in the BITMAPINFO structure. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = bmp.bmWidth; pbmi->bmiHeader.biHeight = bmp.bmHeight; pbmi->bmiHeader.biPlanes = bmp.bmPlanes; pbmi->bmiHeader.biBitCount =4; pbmi->bmiHeader.biCompression = BI_RGB; pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 15)/16 * pbmi->bmiHeader.biHeight * 4; pbmi->bmiHeader.biClrImportant = 0; // Make sure to fill in the rest of the BITMAP info in the header. pBitmapInfoHeader = (PBITMAPINFOHEADER)pbmi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED,pbmi->bmiHeader.biSizeImage); test = GetDIBits(hdc

    J M 2 Replies Last reply
    0
    • T TheDelChop

      Anybody see what the problem is with this code? GetDIBits fails, and when I call GetLastError(), it tells me that Windows "ERROR_FILE_NOT_FOUND". GetClientRect(hDlg, &rc); // Get the rectangle dimensions of the Dialog Box hdc = GetDC(hDlg); // Get a handle to the Drawing Context of the Dialog Box rc.bottom -= (GetSystemMetrics(SM_CYHSCROLL)+GetSystemMetrics(SM_CYEDGE)); hSavedXYContext = CreateCompatibleDC(hdc); // Create a drawing context that is compatiable to // the drawing context on the screen hSavedXYBitmap = CreateCompatibleBitmap(hdc, rc.right-rc.left,rc.bottom-rc.top); hTheDCsOriginalBitmap = (HBITMAP)SelectObject(hSavedXYContext, hSavedXYBitmap); BitBlt(hSavedXYContext,0,0,rc.right-rc.left, rc.bottom-rc.top,hdc,0,0,SRCCOPY); hSavedXYBitmap = (HBITMAP)SelectObject(hSavedXYContext, hTheDCsOriginalBitmap); // As far as I can tell above code does exactly what it should. It grabs a handle to the drawing // context, along with the rectangular coordinates of the drawing context. Then after creating // a compatible bitmap, and selecting it into the saved drawing context, before blting it in. // Now we have the DC saved to hSavedContext, so we need to take it and create a // bitmap file that we can open in Paint. // This involves creating a bmp structure then writing it to a file. GetObject(hSavedXYBitmap,sizeof(BITMAP),(LPSTR)(&bmp)); cClrBits = (WORD)(bmp.bmPlanes*bmp.bmBitsPixel); cClrBits = 4; pbmi = (PBITMAPINFO) LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)); // Initialize the fields in the BITMAPINFO structure. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = bmp.bmWidth; pbmi->bmiHeader.biHeight = bmp.bmHeight; pbmi->bmiHeader.biPlanes = bmp.bmPlanes; pbmi->bmiHeader.biBitCount =4; pbmi->bmiHeader.biCompression = BI_RGB; pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 15)/16 * pbmi->bmiHeader.biHeight * 4; pbmi->bmiHeader.biClrImportant = 0; // Make sure to fill in the rest of the BITMAP info in the header. pBitmapInfoHeader = (PBITMAPINFOHEADER)pbmi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED,pbmi->bmiHeader.biSizeImage); test = GetDIBits(hdc

      J Offline
      J Offline
      John R Shaw
      wrote on last edited by
      #2

      You have to check all the values passed to GetDIBits very carefully. That functions is very touchy and will fail if a single bit is not correct. I do not think the error message has anything to do with the code you are showing, as GeDIBits will often fail without generating any error at all. See CDibData[^], it might help. Note: CDibData has a minor bug that I still have not updated, but it has been a while since I played with graphics.

      INTP "Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra

      1 Reply Last reply
      0
      • T TheDelChop

        Anybody see what the problem is with this code? GetDIBits fails, and when I call GetLastError(), it tells me that Windows "ERROR_FILE_NOT_FOUND". GetClientRect(hDlg, &rc); // Get the rectangle dimensions of the Dialog Box hdc = GetDC(hDlg); // Get a handle to the Drawing Context of the Dialog Box rc.bottom -= (GetSystemMetrics(SM_CYHSCROLL)+GetSystemMetrics(SM_CYEDGE)); hSavedXYContext = CreateCompatibleDC(hdc); // Create a drawing context that is compatiable to // the drawing context on the screen hSavedXYBitmap = CreateCompatibleBitmap(hdc, rc.right-rc.left,rc.bottom-rc.top); hTheDCsOriginalBitmap = (HBITMAP)SelectObject(hSavedXYContext, hSavedXYBitmap); BitBlt(hSavedXYContext,0,0,rc.right-rc.left, rc.bottom-rc.top,hdc,0,0,SRCCOPY); hSavedXYBitmap = (HBITMAP)SelectObject(hSavedXYContext, hTheDCsOriginalBitmap); // As far as I can tell above code does exactly what it should. It grabs a handle to the drawing // context, along with the rectangular coordinates of the drawing context. Then after creating // a compatible bitmap, and selecting it into the saved drawing context, before blting it in. // Now we have the DC saved to hSavedContext, so we need to take it and create a // bitmap file that we can open in Paint. // This involves creating a bmp structure then writing it to a file. GetObject(hSavedXYBitmap,sizeof(BITMAP),(LPSTR)(&bmp)); cClrBits = (WORD)(bmp.bmPlanes*bmp.bmBitsPixel); cClrBits = 4; pbmi = (PBITMAPINFO) LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)); // Initialize the fields in the BITMAPINFO structure. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = bmp.bmWidth; pbmi->bmiHeader.biHeight = bmp.bmHeight; pbmi->bmiHeader.biPlanes = bmp.bmPlanes; pbmi->bmiHeader.biBitCount =4; pbmi->bmiHeader.biCompression = BI_RGB; pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 15)/16 * pbmi->bmiHeader.biHeight * 4; pbmi->bmiHeader.biClrImportant = 0; // Make sure to fill in the rest of the BITMAP info in the header. pBitmapInfoHeader = (PBITMAPINFOHEADER)pbmi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED,pbmi->bmiHeader.biSizeImage); test = GetDIBits(hdc

        M Offline
        M Offline
        Mark Salsbery
        wrote on last edited by
        #3

        I see a few problems -

        TheDelChop wrote:

        GetObject(hSavedXYBitmap,sizeof(BITMAP),(LPSTR)(&bmp));

        Irrelevent, but cast to a LPSTR?? No cast to a void pointer is necessary ;) Problems: Creating a BITMAPINFO the size of a BITMAPINFOHEADER. Using the planes value from the DDB when it HAS to be 1 in a DIB. bmiHeader.biSizeImage is calculated wrong - rows of pixel data in a DIB need to be DWORD aligned. You've provided no color table (16-colors) for your destination 4-bit DIB The resulting GetDIBits call should fail based on the above. Something like this maybe will get you closer:

        ...
        int nNumColors = 1 << cClrBits;

        LONG lBytesPerRow = (((bmp.bmWidth * (long)cClrBits + 31L) & (~31L)) / 8L);

        BYTE* pBitmapBits;

        LONG SizeOfBitmapInfo = sizeof(BITMAPINFO) + ((nNumColors - 1) * sizeof(RGBQUAD));

        BITMAPINFO *pbmi = (PBITMAPINFO) LocalAlloc(LPTR, SizeOfBitmapInfo);
        memset(pbmi, 0, SizeOfBitmapInfo);
        pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pbmi->bmiHeader.biWidth = bmp.bmWidth;
        pbmi->bmiHeader.biHeight = bmp.bmHeight;
        pbmi->bmiHeader.biPlanes = 1;
        pbmi->bmiHeader.biBitCount = cClrBits;
        pbmi->bmiHeader.biCompression = BI_RGB;
        pbmi->bmiHeader.biSizeImage = lBytesPerRow * bmp.bmHeight;
        //pbmi->bmiHeader.biXPelsPerMeter = 0;
        //pbmi->bmiHeader.biYPelsPerMeter = 0;
        //pbmi->bmiHeader.biClrUsed = 0;
        //pbmi->bmiHeader.biClrImportant = 0;

        // I forget if you need to do this before GetDIBits() :doh:
        //// Initialize color table
        //for (int i = 0; i < nNumColors; i++)
        //{
        // pbmi->bmiColors[i].rgbBlue = ;
        // pbmi->bmiColors[i].rgbGreen = ;
        // pbmi->bmiColors[i].rgbRed = ;
        // pbmi->bmiColors[i].rgbReserved = 0;
        //}

        pBitmapInfoHeader = (PBITMAPINFOHEADER)pbmi;

        lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED,pbmi->bmiHeader.biSizeImage);

        test = ::GetDIBits(hdc, hSavedXYBitmap, 0, (WORD) pbmi->bmiHeader.biHeight, lpBits, pbmi, DIB_RGB_COLORS);
        if (test == 0)
        test = GetLastError();

        "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

        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