SDL embed image inside program executable

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-03 06:08:20

问题


Is it possible to embed an image within a program using SDL which can be used at run time.

For example, I have a program which brings up a splash screen on startup containing the logo and copyright information. Rather than having this image in a bitmap file and using SDL_LoadBMP to load it to a SDL_Surface. I would like to have the image embedded in the program binary, to stop someone potentially changing the splash image and copyright name.

Does anyone have any suggestions on ways to do this? Example code would be great.


回答1:


Embedding a file in an executable is easy but there are some gotchas, there are several ways to do it including some portable and non-portable ways.

Convert the image to C code

Write a script to convert the image to a constant array in C. The script would look something like this in Python:

#!/usr/bin/env python3
print("static const unsigned char IMAGE_DATA[] = {{{}}};".format(
        ",".join(str(b) for b in open("myimage.bmp", "rb").read())))

Just pipe the output to a *.h file and include that file from one other file. You can get the size of the file with sizeof(IMAGE_DATA).

Advantages: portable

Disadvantages: requires Python to be installed, does not work if array is too large for compiler, requires adding a custom step to the build system

Convert the image to an object file

This is more platform-dependent. On platforms with GNU binutils toolchains (e.g. Linux) you can use objcopy, I think bin2obj works on Microsoft toolchains.

Advantages: works everywhere

Disadvantages: non-portable, requires adding a custom step to the build system, the custom step might be tricky to get right

On GNU binutils toolchains, with objcopy

The objcopy program lets you specify binary as the input format, but then you need to specify the architecture explicitly... so you will have to modify the command for i386 and x64 versions of your executable.

$ objcopy --input binary --output elf32-i386 --binary-architecture i386 \
    myimage.bmp myimage.o

You can get the data from C by using the following declarations:

// 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))

Use an assembler directive

Paradoxically, embedding a static file is fairly easy in assembler. Assemblers often have directives like .incbin (which works with GAS and YASM).

Advantages: works everywhere

Disadvantages: non-portable, assembler syntax is different between platforms

(Windows) Embed the file as a resource

On Windows, you can embed resources in an EXE and then get the resources using library calls.

Advantages: probably easiest if you are on Windows

Disadvantages: only works on Windows




回答2:


You can export the image as .xpm format (in gimp) and include it to your code. But you will need SDL_Image.h to load it as SDL_Surface.

As it is in this doc, is really simple:

//To create a surface from an XPM image included in C source, use:

SDL_Surface *IMG_ReadXPMFromArray(char **xpm);

A example in C/C++:

#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;
}

I hope this helps.




回答3:


With gimp you can save a image as c code.



来源:https://stackoverflow.com/questions/18422123/sdl-embed-image-inside-program-executable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!