如何为glfwSetWindowIcon加载带透明度的嵌入资源图标
实现方案
推荐方案:零格式转换嵌入PNG
完全不需要把PNG转BMP,也不需要第三方格式转换工具,直接把原始PNG作为自定义资源嵌入即可,从根源避免通道顺序错乱、图像翻转、alpha丢失的问题。
- 第一步:修改资源文件配置,放弃
BITMAP资源类型,用RCDATA原始数据类型嵌入你在绘图软件中导出的32位带透明PNG:100 RCDATA "icons\\icon.png" - 第二步:引入单头文件PNG解码实现stb_image,仅需将头文件放入项目目录,添加如下宏定义后引入头文件即可,无需额外编译配置:
#define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" - 第三步:从程序资源中读取PNG内存,解码后直接传给GLFW设置图标:
// 加载嵌入的PNG资源 HRSRC res_info = FindResource(nullptr, MAKEINTRESOURCE(100), RT_RCDATA); HGLOBAL res_handle = LoadResource(nullptr, res_info); DWORD res_size = SizeofResource(nullptr, res_info); void* png_memory = LockResource(res_handle); // 解码PNG为RGBA格式、自顶向下排列的像素数据 int img_w, img_h, channel_count; unsigned char* pixel_data = stbi_load_from_memory((const stbi_uc*)png_memory, res_size, &img_w, &img_h, &channel_count, 4); // 设置窗口图标 GLFWimage window_icon = { img_w, img_h, pixel_data }; glfwSetWindowIcon(window, 1, &window_icon); // 释放解码占用的内存 stbi_image_free(pixel_data);
这个方案下你不需要对导出的PNG做任何额外处理,全程没有中间格式转换步骤,不会出现颜色错位、图像倒置的问题。
现有BMP方案的修复方式
如果不想引入PNG解码代码,继续沿用当前的BMP加载逻辑,只需要修复通道顺序问题即可:
你遇到的RGB顺序翻转本质是Win32 GDI的GetDIBits接口返回的32位像素数据是BGR(A)排列,每个像素4字节依次为蓝、绿、红、Alpha通道,但GLFWimage要求传入的像素是RGBA排列,红蓝通道位置互换就会导致颜色显示异常。
修复逻辑非常简单,在GetDIBits调用完成后,遍历所有像素交换红蓝通道即可:
for (size_t i = 0; i < pixels.size(); i += 4) { unsigned char swap_temp = pixels[i]; pixels[i] = pixels[i+2]; pixels[i+2] = swap_temp; }
另外你通过给BITMAPINFOHEADER.biHeight赋值为负数修复图像倒置的写法兼容性较差,部分旧版本Windows对自顶向下DIB的支持存在问题,建议将biHeight设为正的位图高度,拿到自底向上排列的像素数据后逐行翻转,稳定性更高。
内容的提问来源于stack exchange,提问作者user11813319
相关产品推荐
相关产品推荐

