Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Load an HBITMAP into SFML sf::Image container

0.00/5 (No votes)
5 Feb 2013 1  
Use the standard GDI API to load an HBITMAP into SFML.

Introduction

A simple function to load a bitmap in Win32 GDI to be used by the Sprite-class for SFML.

Using the code

The code is a simple function that you can copy and paste into your Win32 project:

//////////////////////////////////////////////////////////////////////////
// Function created by: Lars Werner - http://lars.werner.no
//////////////////////////////////////////////////////////////////////////
// Inputs:    [in] HBITMAP hBitmap = A HBITMAP handle
//            [out] sf::Image *pPicture = A image in SFML as pointer
//
//////////////////////////////////////////////////////////////////////////
// Return:    True if loaded, False if not!
//            The pPicture is the variable set and to be used further on
//////////////////////////////////////////////////////////////////////////
// Version: 1.0 = Inital Release
//////////////////////////////////////////////////////////////////////////
bool SFMLLoadHBitmapAsImage(HBITMAP hBitmap, sf::Image *pPicture)
{
    //Create a DC to get hBitmap information
    HDC hDC = GetDC( ::GetDesktopWindow() );
 
    //Create BITMAPINFO variable, set size 
    BITMAPINFO MyBMInfo = {0};
    MyBMInfo.bmiHeader.biSize = sizeof( MyBMInfo.bmiHeader );
 
    //Get the BITMAPINFO structure from the bitmap
    if( 0 == GetDIBits(hDC, hBitmap, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS))
    {
        // error handling
        return false;
    }
 
    //Create the bitmap pixel array each element is [b,g,r]
    BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];
 
    //Setting up the structure of the buffer to be received
     MyBMInfo.bmiHeader.biCompression = BI_RGB;  // No-compression
 
    //Now get the actual data from the picture
    if (0 == GetDIBits(hDC, hBitmap, 0, MyBMInfo.bmiHeader.biHeight, (LPVOID)lpPixels, &MyBMInfo, DIB_RGB_COLORS))
    {
        // error handling
        return false;
    }
 
    //Now create an array of SFML pixels we want to fill
    sf::Uint8 *lpPixelWithAlpha = new sf::Uint8[ MyBMInfo.bmiHeader.biSizeImage + 
          (MyBMInfo.bmiHeader.biSizeImage/3)/3 ]; //Add room for alpha
 
    //Loop through each pixel, with steps of four RGBA!
    for(int x=0;x<MyBMInfo.bmiHeader.biSizeImage;x+=4)
    {
        lpPixelWithAlpha[x] = lpPixels[x+2];    //lpPixels = r
        lpPixelWithAlpha[x+1] = lpPixels[x+1];    //lpPixels = g
        lpPixelWithAlpha[x+2] = lpPixels[x];    //lpPixels = b
        lpPixelWithAlpha[x+3] = 255;        //Nada alpha (just to adjust if you like)
    }
 
    //Remove old DIBsection
    delete[] lpPixels;
 
    //Load picture, now with correct pixels and alpha channel
    if( false == pPicture->LoadFromPixels(MyBMInfo.bmiHeader.biWidth, 
                  MyBMInfo.bmiHeader.biHeight, lpPixelWithAlpha))
    {
        // error handling
        return false;
    }
 
    //Remove the pixels with alphachannel
    delete[] lpPixelWithAlpha;
 
    //Release the DC
    ReleaseDC(::GetDesktopWindow(), hDC);
 
    //Notify ok!
    return true;
} 

To use the function in your load-procedure, use it like this. Note that the Screenshot function can be located here.

//Create a container for the picture
sf::Image m_mypicture;
 
//Get a HBITMAP (see function from before)
HBITMAP hBitmap = ScreenShot( http://lars.werner.no/?p=627 <--- function and parameters here );
 
//Run the function
if( false == SFMLLoadHBitmapAsImage(hBitmap, &my_picture) )
{
// error handling
}
 
//Load your image into the sprite
sf::Sprite m_mysprite.SetImage(m_mypicture);
 
//The DIB section begins with the last pixels at the beginning.
//Since SFML have flip-functions I didn't care to fix it :)
m_mysprite.FlipY(true); 

Got any other ways to do this? Please comment. If other formats are needed, an integration with GDI+ could be made, it natively supports PNG, GIF, JPG, etc...

History   

  • v1.0 - First release (and probably the only release).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here