使用SDL在程序中嵌入图片并在运行时使用,这是否可能?
例如,我有一个程序,在启动时显示一个包含标志和版权信息的启动画面。与其将此图像放在位图文件中,并使用SDL_LoadBMP将其加载到SDL_Surface中,我希望将图像嵌入程序二进制文件中,以防止某人潜在地更改启动画面和版权名称。
有什么建议可以做到这一点吗?示例代码将非常好。
将文件嵌入可执行文件很容易,但有一些需要注意的地方。有几种方法可以实现,包括一些便携式和非便携式的方法。
据报道,这将成为C23的一部分。它也可能在C++26中出现。请检查您的编译器是否支持此功能。未来,这可能是嵌入二进制数据最具可移植性和直接的方式。
static const unsigned char IMAGE_DATA[] = {
#embed "myimage.bmp
};
有关功能提案,请参见WG14 n2592。
优点:最简单、最容易的。
缺点:你的编译器可能还不支持此功能。
编写一个脚本,将图像转换为C语言中的常量数组。 在Python中,该脚本看起来会像这样:
#!/usr/bin/env python3
print("static const unsigned char IMAGE_DATA[] = {{{}}};".format(
",".join(str(b) for b in open("myimage.bmp", "rb").read())))
只需将输出导入一个*.h
文件中,并从另一个文件中包含该文件。您可以使用sizeof(IMAGE_DATA)
获取文件的大小。
优点:可移植性强
缺点:需要安装Python,如果数组太大而无法编译,则无法工作,需要向构建系统添加自定义步骤
这更具平台依赖性。 在具有GNU binutils工具链(例如Linux)的平台上,可以使用objcopy
,我认为bin2obj
适用于Microsoft工具链。
优点:在任何地方都有效
缺点:不可移植,需要向构建系统添加自定义步骤,自定义步骤可能难以正确实现
objcopy
程序允许您将binary
指定为输入格式,但是然后您需要明确指定架构...因此,您将不得不修改i386和x64版本可执行文件的命令。
$ objcopy --input binary --output elf32-i386 --binary-architecture i386 \
myimage.bmp myimage.o
你可以使用以下声明从 C 中获取数据:
// Ignore the fact that these are char...
extern char _binary_myimage_bmp_start, _binary_myimage_bmp_end;
#define MYIMAGE_DATA ((void *) &_binary_myimage_bmp_start)
#define MYIMAGE_SIZE \
((size_t) (&_binary_myimage_bmp_end - &_binary_myimage_bmp_start))
具有讽刺意味的是,在汇编语言中嵌入静态文件相当容易。汇编器通常具有像.incbin
这样的指令(适用于GAS和YASM)。
优点:适用于任何平台
缺点:不可移植,汇编语法在不同平台上不同
在Windows上,您可以将资源嵌入EXE文件中,然后使用库调用获取资源。
优点:如果您在Windows上,则可能是最简单的方法
缺点:只适用于Windows操作系统
objcopy
的指令。 - Dietrich Eppimage.h
文件后,我该如何在 c++ 中使用它呢?例如,在 qt 中通常可以将字符串设置为图像文件路径(string str1 = str0 + "splash.png";QPixmap pixmap(str1.c_str());
)。现在我应该怎么做才能使用 image.h
文件呢?谢谢。 - Daniel//To create a surface from an XPM image included in C source, use:
SDL_Surface *IMG_ReadXPMFromArray(char **xpm);
#include <SDL/SDL.h>
#include "test.xpm"
#include <SDL/SDL_image.h>
SDL_Surface *image;
SDL_Surface *screen;
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode(800,600,32,SDL_SWSURFACE);
image = IMG_ReadXPMFromArray(test_xpm); //the .xpm image is a char array. "test_xpm" is the name of the char array
SDL_Rect offset;
offset.x = 0;
offset.y = 0;
SDL_BlitSurface(image,NULL,screen,&offset);
SDL_Flip(screen);
SDL_Delay(5000);
return 0;
}
我希望这能有所帮助。
使用GIMP,你可以将图片保存为C代码。
SDL_RWOps
与调用SDL_LoadBMP_RW()
可以从任何你配置它的地方获取图像,包括在编译时构建的静态内部缓冲区。无论这是否“解决”了您正在识别的问题是另一回事。 - WhozCraigSDL_RWOps
来使用一个自定义函数集(由你编写),该函数集将该图像作为其数据“源”。你明白我的意思。 - WhozCraig