开发者

Loading an image from resource and converting to bitmap in memory

I've searched around using google but I'm completely confused on how to load an image (PNG in my case) from resource and then converting it to a bitmap i开发者_运维百科n memory for use in my splash screen. I've read about GDI+ and libpng but I don't really know how to do what I want. Could anyone help?


GDI+ supports PNG directly. See here and here.

EDIT: The GDI+ documentation offers some advice for how to use GDI+ in a DLL. In your case, the best solution is probably to define initialisation and teardown functions that the client code is required to call.


I ended up using PicoPNG to convert the PNG to a two dimensional vector which I then manually contructed a bitmap from. My final code looked like this:

HBITMAP LoadPNGasBMP(const HMODULE hModule, const LPCTSTR lpPNGName)
{
    /* First we need to get an pointer to the PNG */
    HRSRC found = FindResource(hModule, lpPNGName, "PNG");
    unsigned int size = SizeofResource(hModule, found);
    HGLOBAL loaded = LoadResource(hModule, found);
    void* resource_data = LockResource(loaded);

    /* Now we decode the PNG */
    vector<unsigned char> raw;
    unsigned long width, height;
    int err = decodePNG(raw, width, height, (const unsigned char*)resource_data, size);
    if (err != 0)
    {
        log_debug("Error while decoding png splash: %d", err);
        return NULL;
    }

    /* Create the bitmap */
    BITMAPV5HEADER bmpheader = {0};
    bmpheader.bV5Size = sizeof(BITMAPV5HEADER);
    bmpheader.bV5Width = width;
    bmpheader.bV5Height = height;
    bmpheader.bV5Planes = 1;
    bmpheader.bV5BitCount = 32;
    bmpheader.bV5Compression = BI_BITFIELDS;
    bmpheader.bV5SizeImage = width*height*4;
    bmpheader.bV5RedMask = 0x00FF0000;
    bmpheader.bV5GreenMask = 0x0000FF00;
    bmpheader.bV5BlueMask = 0x000000FF;
    bmpheader.bV5AlphaMask = 0xFF000000;
    bmpheader.bV5CSType = LCS_WINDOWS_COLOR_SPACE;
    bmpheader.bV5Intent = LCS_GM_BUSINESS;
    void* converted = NULL;
    HDC screen = GetDC(NULL);
    HBITMAP result = CreateDIBSection(screen, reinterpret_cast<BITMAPINFO*>(&bmpheader), DIB_RGB_COLORS, &converted, NULL, 0);
    ReleaseDC(NULL, screen);

    /* Copy the decoded image into the bitmap in the correct order */
    for (unsigned int y1 = height - 1, y2 = 0; y2 < height; y1--, y2++)
        for (unsigned int x = 0; x < width; x++)
        {
            *((char*)converted+0+4*x+4*width*y2) = raw[2+4*x+4*width*y1]; // Blue
            *((char*)converted+1+4*x+4*width*y2) = raw[1+4*x+4*width*y1]; // Green
            *((char*)converted+2+4*x+4*width*y2) = raw[0+4*x+4*width*y1]; // Red
            *((char*)converted+3+4*x+4*width*y2) = raw[3+4*x+4*width*y1]; // Alpha
        }

    /* Done! */
    return result;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜