【问题标题】:Loading an image from resource and converting to bitmap in memory从资源加载图像并转换为内存中的位图
【发布时间】:2012-01-18 16:35:35
【问题描述】:

我已经使用 google 进行了搜索,但对于如何从资源加载图像(在我的情况下为 PNG)然后将其转换为内存中的位图以在我的启动画面中使用,我完全感到困惑。我已经阅读了有关 GDI+ 和 libpng 的信息,但我真的不知道如何做我想做的事。有人可以帮忙吗?

【问题讨论】:

  • 如果您可以使用 JPEG,那么 OleLoadPicture 和朋友们应该可以解决问题。
  • 但我认为没有任何方法可以在不压缩的情况下存储 JPEG 文件...而且我需要保留 alpha 通道

标签: c++ image resources bitmap


【解决方案1】:

GDI+ 直接支持 PNG。见herehere

编辑:GDI+ documentation 提供了一些关于如何在 DLL 中使用 GDI+ 的建议。在您的情况下,最好的解决方案可能是定义客户端代码需要调用的初始化和拆卸函数。

【讨论】:

  • 好的。似乎我不能将 GDI+ 用于我正在做的事情,因为这一切都是在 DllMain 和它调用的函数中完成的。您还有其他建议吗?
  • 如果我可以编辑调用 dll 的程序,我会这样做(我读过它),但我不能。所以我真的不认为我可以使用 GDI+。我目前正在研究使用 WIC 将我的 PNG 转换为 HBITMAP
【解决方案2】:

我最终使用PicoPNG 将 PNG 转换为二维矢量,然后我手动从中构建了位图。我的最终代码如下所示:

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 2012-11-15
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    相关资源
    最近更新 更多