c++ - SDL 在程序可执行文件中嵌入图像

标签 c++ c image bitmap sdl

是否可以使用可在运行时使用的 SDL 在程序中嵌入图像。

例如,我有一个程序可以在启动时显示包含 Logo 和版权信息的启动画面。而不是将此图像放在位图文件中并使用 SDL_LoadBMP 将其加载到 SDL_Surface。我想将图像嵌入到程序二进制文件中,以阻止有人可能更改启动图像和版权名称。

有没有人对如何做到这一点有任何建议?示例代码会很棒。

最佳答案

将文件嵌入可执行文件很容易,但也有一些问题,有几种方法可以做到这一点,包括一些可移植和不可移植的方法。

使用#embed

据报道,这将是 C23 的一部分。它也可能会出现在 C++26 中。检查您的编译器是否支持此功能。将来,这可能是嵌入二进制数据的最便携、最直接的方式。

static const unsigned char IMAGE_DATA[] = {
#embed "myimage.bmp
};

参见 WG14 n2592用于功能提案。

优点:最简单,最容易

缺点:你的编译器可能还不支持

将图像转换成C代码

用 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 工具链。

优点:无处不在

缺点:不可移植,需要在构建系统中添加自定义步骤,自定义步骤可能很难正确执行

在 GNU binutils 工具链上,带有 objcopy

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) 将文件作为资源嵌入

在 Windows 上,您可以将资源嵌入到 EXE 中,然后使用库调用获取资源。

优点:如果你在 Windows 上,可能最简单

缺点:仅适用于Windows

关于c++ - SDL 在程序可执行文件中嵌入图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18422123/

相关文章:

c++ - C++ 中的整数输入验证

c++ - STL Vectors 和 new 运算符

C 文件处理/结构问题

html - 如何在大屏幕中显示完整的背景图像?

c++ - 命令提示符中的字符 '<'

c++ - boost::线程生产者消费者

c - 以最简单的形式使用 fork() 需要按回车键才能完成执行

c - C语言进程同步

javascript - 循环浏览 Canvas 图像以找到(几乎)纯色的最大点

html - 基于 css 类调整响应式图像大小