18 votes

SDL intègre une image dans l'exécutable du programme

Est-il possible d'intégrer une image dans un programme à l'aide de SDL et de l'utiliser au moment de l'exécution.

Par exemple, j'ai un programme qui affiche au démarrage un écran de démarrage contenant le logo et les informations sur les droits d'auteur. Plutôt que d'avoir cette image dans un fichier bitmap et d'utiliser SDL_LoadBMP pour la charger dans une SDL_Surface. J'aimerais que l'image soit intégrée dans le binaire du programme, afin d'éviter que quelqu'un ne modifie l'image de démarrage et le nom du copyright.

Quelqu'un a-t-il des suggestions sur la façon de procéder ? Un exemple de code serait le bienvenu.

19voto

Dietrich Epp Points 72865

Intégrer un fichier dans un exécutable est facile, mais il y a quelques problèmes. Il y a plusieurs façons de le faire, dont certaines sont portables et d'autres non.

Convertir l'image en code C

Ecrivez un script pour convertir l'image en un tableau constant en C. Le script ressemblerait à ceci en Python :

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

Il suffit d'acheminer la sortie vers un *.h et inclure ce fichier dans un autre fichier. Vous pouvez obtenir la taille du fichier avec sizeof(IMAGE_DATA) .

Avantages : portable

Inconvénients : nécessite l'installation de Python, ne fonctionne pas si le tableau est trop grand pour le compilateur, nécessite l'ajout d'une étape personnalisée au système de construction.

Convertir l'image en fichier objet

Cela dépend davantage de la plate-forme. Sur les plates-formes dotées d'une chaîne d'outils GNU binutils (par exemple Linux), vous pouvez utiliser objcopy Je pense que bin2obj fonctionne avec les chaînes d'outils Microsoft.

Avantages : fonctionne partout

Inconvénients : non portable, nécessite l'ajout d'une étape personnalisée au système de construction, l'étape personnalisée peut être difficile à mettre en place.

Sur les chaînes d'outils GNU binutils, avec objcopy

En objcopy vous permet de spécifier binary comme format d'entrée, mais vous devez alors spécifier explicitement l'architecture... vous devrez donc modifier la commande pour les versions i386 et x64 de votre exécutable.

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

Vous pouvez obtenir les données à partir de C en utilisant les déclarations suivantes :

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

Utiliser une directive de l'assembleur

Paradoxalement, l'intégration d'un fichier statique est assez facile en assembleur. Les assembleurs ont souvent des directives comme .incbin (qui fonctionne avec GAS et YASM).

Avantages : fonctionne partout

Inconvénients : non portable, la syntaxe de l'assembleur diffère d'une plate-forme à l'autre.

(Windows) Intégrer le fichier en tant que ressource

Sous Windows, vous pouvez intégrer des ressources dans un fichier EXE et obtenir ces ressources par le biais d'appels de bibliothèque.

Avantages : probablement le plus simple si vous êtes sous Windows

Inconvénients : ne fonctionne que sous Windows

4voto

drift3r Points 41

Vous pouvez exporter l'image au format .xpm (dans gimp) et l'inclure dans votre code. Mais vous aurez besoin de SDL_Image.h pour la charger en tant que SDL_Surface.

Comme c'est le cas dans este est très simple :

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

SDL_Surface *IMG_ReadXPMFromArray(char **xpm);

Un exemple en 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;
}

J'espère que cela vous aidera.

3voto

carlos Points 787

Avec gimp, vous pouvez enregistrer une image en code c.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X