Thread: Loading bitmap file into a HBITMAP

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    6

    Loading bitmap file into a HBITMAP

    Hi everyone, I am having a problem loading bitmap files. I have gone through various tutorials that I've found on the web, but with little success. I am using the win32 api, no MFC or SDL, just win32 api code.

    I already know how to load the image using LoadImage, but this does not meet my requirements. I need to be able to load the bitmap into a memory DC, assign a HBITMAP handle to it so I can BitBlt it to my needs. Can anyone offer any suggestions as to what I am doing wrong...The images I am using are all 24bit, and from what I have read this means that I do not need to worry about palettes? When stepping through the code in debug, I can see that the FILEHEADER and INFOHEADER are read in correctly, and when I use GetObject on the HBITMAP returned from CreateDIBitmap, it gives me the right width and height, but I did notice that it shows 1 bits per pixel, should this not be 24 ?

    HDC hdcmem = CreateCompatibleDC(hdc);
    BITMAP bmMem;
    HBITMAP hbmMem, hbmFinal;


    BITMAPFILEHEADER bmfh;
    BITMAPINFOHEADER bmih;

    ifstream bmf("C:\\cpp\\bitmap\\example.bmp", ios_base::in | ios_base::binary);
    if(!bmf.is_open())
    exit(-1);

    bmf.read(reinterpret_cast<char *>(&bmfh), sizeof(BITMAPFILEHEADER));
    if(bmfh.bfType != 19778)
    exit(-1);
    long bmsize = bmfh.bfSize - bmfh.bfOffBits;
    bmf.read(reinterpret_cast<char *>(&bmih), sizeof(BITMAPINFOHEADER));
    int bmcolors = bmih.biClrUsed ? bmih.biClrUsed : 1 << bmih.biBitCount;

    char *bmdata = new char[bmsize];
    bmf.read(bmdata, bmsize);
    bmf.close();

    hbmfile = CreateDIBitmap(hdcMem, &bmih, CBM_INIT, bmdata, (BITMAPINFO *)&bmih, DIB_RGB_COLORS);
    hbmFinal = (HBITMAP)SelectObject(hdcMem, hbmfile);
    GetObject(hbmfile,sizeof(bmMem), &bmMem);

    .
    .
    .

    BitBlt(hdc, 0,0, bmMem.bmWidth, bmMem.bmHeight,hdcMem,0,0,SRCCOPY);

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    So is that what your code really looks like, or did you rip out all the braces to get past the code checking tool which is designed to remind people to use [code][/code] tags whenever they post code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2007
    Posts
    6
    No this is not all the code! What I basically need to do is be able to read a bitmap file into a memory DC. I can load it no problem and display it straight to the screen using SetDIBitsToDevice(), however I need to be able to read it into a memory DC first so I can BitBlt it myself when needed. I have tried using CreateDIBitmap() with no success. Do I need to do some more conversion on the bitmap before I can use it in a memory DC?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Moved to windows board, since this is more win32 API specific.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by wind_addict View Post
    I already know how to load the image using LoadImage, but this does not meet my requirements. I need to be able to load the bitmap into a memory DC, assign a HBITMAP handle to it so I can BitBlt it to my needs.

    LoadImage() returns a HANDLE, which you can cast to a HBITMAP.
    Create a compatible DC
    SelectObject() the bitmap into the memory DC
    Draw with BitBlt()
    Clean up GDI
    Call for a paint


    ** Note code written from memory so may not work..... **

    Code:
    //load image
    HBITMAP   hBMP = (HBITMAP*) LoadImage( hInst, "..\\Res\\SomeImage.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    
    //get a compatible DC
    HDC   hDC = GetDC( NULL);//whole screen
    //get mem DC
    HDC hMemDC = CreateCompatibleDC(hDC);
    //select in our bitmap
    hBITMAP hOrigBMP = (HBITMAP*) SelectObject(hMemDC, hBMP);
    
    //use hMemDC to draw bitmap to screen DC (hDC)
    
    //clean up
    //put hMemDC back the way we created it
    SelectObject(hMemDC, hOrigBMP);
    //delete, release
    ReleaseDC(hDC);
    DeleteObject(hBMP);
    DeleteObject(hMemDC);
    
    //call for a paint
    InvalidateRect(hWnd, NULL, FALSE);
    UpdateWindow(hWnd);
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  6. #6
    Registered User
    Join Date
    Nov 2007
    Posts
    6
    Hi Novacain, I think my quesiton is confusing, I already know how to load an image that way, I would like to be able to load the bitmap using binary, then assign it a HBITMAP handle so I can use it.

    I can successfully load the bitmap into an array of char and successfully display it to the screen using SetDIBitsToDevice(). BUT, this only works when I specify the screen hdc, ie SetDIBitsToDevice(hdc, .......). I don't want to display the bitmap immediately, I want to save it to a HBITMAP handle so I can BitBlt it to the screen later one when I need it. I have tried using SetDIBitsToDevice(memhdc, ......) but that does not work. I have also tried using CreateDIBitmap function into the memhdc, select the hbitmap into the memdc, and try and bitblt that, but nothing appears.

  7. #7
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Why?

    Why not load the bitmap as I suggested,
    select into a memDC for drawing ect
    and then save the bitmap again (from the HBITMAP) when required?

    Use one of the screen capture codes posted here (do a search).
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  8. #8
    Registered User
    Join Date
    Nov 2007
    Posts
    6
    Quote Originally Posted by novacain View Post
    Why?

    Why not load the bitmap as I suggested,
    select into a memDC for drawing ect
    and then save the bitmap again (from the HBITMAP) when required?

    Use one of the screen capture codes posted here (do a search).
    Why not? Instead of asking me to justify my reasons for needing to read a bitmap in such a manner, how about some constructive comments/tips on what I might need to do? If you don't know how to do it, then maybe just don't post at all! As I have mentioned I think 3 times now, I KNOW how to do it using loadimage().

    As it turns out I have figured it out by myself, quite simple now that I have got it working.

    This is how I did it, maybe you should read it and next time someone asks, you will know the answer!

    Read the bitmap file into a char array,

    hdcmem = CreateCompatibleDC(hdc)
    hbm = CreateCompatibleBitmap(hdc)
    SelectObject(hdcmem, hbm)
    SetDIBitsToDevice(hdcmem, ..........)

    and there I can now BitBlt it to the screen when I wish.

  9. #9
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Prahaps if you had posted full code, or used code tags, I would have noticed that you were trying to draw a large bitmap to the 1x1 monochrome bitmap that is created in any compatible DC (rather than creating a compatible bitmap as well).

    Good luck with WIN32 GDI.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    @wind_addict:

    So let me get this straight. You ask a question and someone is gracious enough to help you. And BTW novacain is no slouch and knows a whole lot about Win32 and MFC. Then you proceed to bash him in later posts?

    That makes you extremely rude. Show some decency and respect. I might be wrong but I would say that you are on your own now in Win32 GDI since you obviously already know everything anyways.

    I've got an idea. If you ask a question then heed the answer. There are many ways to do things in Win32 and novacain posted the simplest solution. Just because you do not like it does not mean its wrong.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  2. Inventory records
    By jsbeckton in forum C Programming
    Replies: 23
    Last Post: 06-28-2007, 04:14 AM
  3. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM
  4. Error when loading 3ds file
    By The Wazaa in forum C++ Programming
    Replies: 6
    Last Post: 01-24-2006, 08:27 AM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM