目录

将图片内嵌到 exe 文件中

场景描述:

如果程序中需要使用一张图片,通常会用相对路径方式指定一个外部文件。例如:

loadimage(NULL, "test.jpg");

这样,将编译后的 .exe 和 test.jpg 放在一起,就可以正确加载图片。许多游戏有几十个甚至上千个文件,就是有类似这样的许多外部数据。

但还有一些情况,希望图片能嵌入编译后的 .exe 里面,这样只需要拷贝一个 .exe 文件就能附带上所需图片。本文就介绍这种情况的实现方法。

什么是资源文件:

windows 应用程序是可以包含各种“资源”的,例如:图标、对话框、菜单、快捷键等等,这些资源按照一定的格式,可以和 .exe 链接在一起。

我们所要做的,就是把图片放到资源中,然后从资源中加载图片。

操作步骤:

以英文版的 VC6 和 VC2010 为例,嵌入资源的操作步骤如下:

1. 创建项目

打开 VC6(或 VC2010 等其他版本),建立控制台应用程序,并建立相应 cpp 程序,确保可以正确编译执行。

2. 创建资源文件

对于 VC6:点菜单 File -> New...,选择 Files 中的 Resource Script,并在右侧 File 中写入名称 test,点 OK 添加到项目中。VC 会默认打开 test.rc 文件,先关闭它,我们可以 FileView 找到新添加的 test.rc 文件。双击 test.rc,会在 Workspace 区中打开 Resource View 视图。

对于 VC2010:在 Solution Explorer 中找到 Resource Files,右击,选择 Add -> New Item...,在弹出的新窗口中选择 Resource File (.rc),在 Name 中写入名称 test,点 Add 添加。此时会自动切换到 Resource View 视图的选项卡。

在新打开的 Resource View 视图中,会显示本项目中使用的资源,例如图标、位图、字符串等等。当然,现在还是空的。

3. 添加图片到资源文件中

3-1. 为了整齐,我们在项目路径下建立 res 文件夹,并将图片放入该文件夹内。举例,我们放入一个 bk.jpg 文件。

3-2. 添加 JPG 资源。

对于 VC6:切换到 ResourceView 视图,右击 test resources,选择 Import...,导入 res\bk.jpg 文件。之后在 Custom Resource Type 中为资源取一个类型名称,例如"IMAGE",点 OK。此时 VC 会在"IMAGE"下默认创建一个 IDR_IMAGE1 的资源,并以二进制形式打开。我们暂时关掉它。

对于 VC2010:切换到 Resource View 视图,右击 test.rc,选择 Add Resource...,在弹出的窗口中点 Import... 按钮,选择 res\bk.jpg 文件。之后在 Custom Resource Type 中为资源取一个类型名称,例如"IMAGE",点 OK。此时 VC 会在"IMAGE"下默认创建一个 IDR_IMAGE1 的资源,并以二进制形式打开。我们暂时关掉它。

3-3. 重命名资源。

对于 VC6:右击 IDR_IMAGE1,选 Properties,将 ID 一栏的 IDR_IMAGE1 修改为符合其意义的名称,例如"Background",切忌,一定要加上英文的双引号。这时,资源中可以看到 "IMAGE" / "Background" (注意都有双引号)。

对于 VC2010:选中 IDR_IMAGE1,按 Alt + Enter 显示 Properties,将 ID 一栏的 IDR_IMAGE1 修改为符合其意义的名称,例如"Background",切忌,一定要加上英文的双引号。这时,资源中可以看到 "IMAGE" / "Background" (注意都有双引号)。

4. 加载资源中的图片

加载图片很简单,只需要指定“资源类型”和“资源名称”。例如我们前面的例子,资源类型是 "IMAGE",资源名称是 "Background",将这个图片资源显示在绘图窗体上可以这样做:

loadimage(NULL, _T("IMAGE"), _T("Background"));

最后,编译程序,图片就会自动和 exe 打包在一起。

特殊情况 1:以资源 ID 的形式加载资源图片

使用图片的资源 ID 也是一种常用的加载资源的方法。默认情况下,将图片导入资源后,会自动生成一个 ID,并且会在 resource.h 里面定义这个 ID。这里说的,就是直接引用这个 ID 而不命名为字符串。

为了实现这个目的,需要首先引用资源头文件,然后用宏 MAKEINTRESOURCE 将 ID 转换为字符串。例如加载一个名称为 IDR_BACKGROUND 的资源:

#include "resource.h"
……
loadimage(NULL, _T("IMAGE"), MAKEINTRESOURCE(IDR_BACKGROUND));

特殊情况 2:将 BMP 格式的图片嵌入资源

由于 BMP 图片在资源中的情况特殊,导入资源后,会导致文件头丢失,从而引起加载失败。

所以,需要明确指定 BMP 图片的资源类型为其它类型,方法如下:

1. 在资源中导入 test.bmp 图片。默认会导入在 Bitmap 类别下,并命名为 IDB_BITMAP1。作为范例,我们修改这个资源 ID 为字符串“test_bmp”。编译项目,确保没有错误。

2. 以文本方式打开资源文件。

对于 VC6,点菜单 File -> Open...,选中项目的资源文件 test.rc,底部的 Open as 选择 Text,点 Open 打开(如果此时资源视图已打开,会提示“This file is open for resource editing. Continuing will close the resource editor.”,点 OK)。

对于 VC2010,在 Solution Explorer 里面找到资源文件 test.rc,右击,选择 View Code(如果此时资源视图已打开,会提示“The document 'xxx' is already open. Do you want to close it?”,点 Yes)。

这样就可以以文本方式打开资源文件。

3. 在资源文件的文本中,找到这样的内容:

/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//

test_bmp		BITMAP	DISCARDABLE	"test.bmp"
然后将这一行里面的 BITMAP 修改为自己定义的一个类型,例如 IMAGE:
test_bmp		IMAGE	DISCARDABLE	"test.bmp"
然后就可以按照前述方式加载这个图片资源,例如:
loadimage(NULL, _T("IMAGE"), _T("test_bmp"));