.rc文件是windows原生资源编译唯一入口,需用rc.exe将图片转为二进制块再链接;路径须相对于项目根目录,id须为整数或宏,类型声明bitmap不校验实际格式;跨平台应改用c数组或qrc;路径、符号、初始化三者必须严格匹配。

Windows平台用.rc文件嵌入图片资源
Visual Studio项目里,.rc是唯一被原生支持的资源编译入口。你不能直接把PNG塞进EXE,得靠RC编译器(rc.exe)转成二进制块,再由链接器合并进去。
常见错误是把图片路径写成相对路径却没设工作目录——rc.exe默认在项目根目录找文件,不是在.rc同目录。结果编译报错:fatal error RC1015: cannot open include file 'res/icon.png'。
- 资源ID必须是整数或已定义的宏(如
#define IDB_LOGO 101),别用字符串名 - 图片类型写
BITMAP(即使你放的是PNG,RC工具只认格式声明,不校验内容) - VS中右键
.rc→ “属性” → “排除于生成”必须设为“否”,否则资源根本不会编译
LOGO_IMAGE BITMAP "res\logo.png"
运行时加载BITMAP资源要绕过GDI+限制
LoadImage和LoadBitmap只能加载BITMAP资源,但返回的是HBITMAP,没法直接喂给现代UI库(比如Qt的QPixmap或Direct2D的ID2D1Bitmap)。你得手动提取像素数据。
容易踩的坑:用GetDIBits前忘了创建兼容DC,或者没调GetObject查真实位深度,导致内存拷贝错位、图片发绿或全黑。
立即学习“C++免费学习笔记(深入)”;
- 先
LoadImage(NULL, MAKEINTRESOURCE(IDB_LOGO), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION),加LR_CREATEDIBSECTION才能拿到可读像素指针 - 用
GetObject(hbmp, sizeof(BITMAP), &bm)确认bm.bmBitsPixel是24还是32——很多PNG导出带Alpha,但BITMAP资源默认不存Alpha通道 - 如果原图是PNG且需要透明度,别走RC路线,改用Base64编码嵌入或单独打包资源DLL
跨平台方案别碰.rc,改用编译期二进制注入
Linux/macOS没有rc.exe,CMake或Meson项目里硬塞.rc等于自废武功。更通用的做法是把图片转成C数组,用objcopy或xxd生成.o文件。
典型错误是用xxd -i logo.png生成的数组名含点号(如logo_png),但C++变量名不允许点,GCC会静默失败,链接时报undefined reference to 'logo_png'。
- 用
xxd -i -n logo_data logo.png > logo.h指定符号名,避免非法字符 - 在C++里
extern "C" const unsigned char logo_data[];声明,别漏extern "C"——C++ name mangling会让链接器找不到符号 - 数组大小得另声明:
extern "C" const unsigned int logo_data_len;,xxd会自动生成
Qt项目里用qrc比.rc更省事但要注意构建时机
如果你用Qt,.qrc是更自然的选择,:/images/logo.png路径能直接传给QPixmap。但它不是编译进EXE,而是打包进Qt的资源系统,依赖Q_INIT_RESOURCE初始化。
最常被忽略的一点:CMake项目里没调qt_add_resources,或.qrc文件没加到add_executable源列表,结果运行时QPixmap(":/images/logo.png")构造失败,isNull()返回true,但没有任何错误提示。
- 确保
.qrc文件在CMakeLists.txt中被qt_add_resources处理,不是简单当成普通源文件 - 在main()开头加
Q_INIT_RESOURCE(your_resource_name);,名字取自<rcc></rcc>标签里的name属性,不是文件名 - 调试时用
QDir::setCurrent("qrc:/")再QDir().entryList()看资源是否真加载了










