2014-09-04 3 views
2

Tout d'abord, bonjour là-bas!Création de grandes images

puis, un peu de contexte:

Je travaille actuellement sur un « générateur Maze ». Je peux, pour l'instant, générer des labyrinthes avec 18500 largeurs et 18500 hauteurs (ce qui me rend un peu heureux !!).

Donc, pas de problème avec la génération. Puis, bien sûr, je voulais les écrire dans un fichier .jpeg/.bmp ou d'autres fichiers. Donc, pour un labyrinthe de 18k5 * 18k5, j'ai besoin d'une image de 37k * 37k.

J'ai d'abord essayé avec .jpeg. Cela a fonctionné, mais les fichiers de sortie étaient grands de 1,2 GigaBytes. Ceux-ci prennent des âges trop ouverts ... mais je peux les ouvrir.

J'ai donc essayé d'utiliser le format BMP à la place car il permet d'encoder des pixels sur 1 bit chacun. Les fichiers de sortie sont maintenant reaaaally plus petits .... mais je ne peux pas les ouvrir ... On me dit que les fichiers sont "corrompus ou trop gros". Je ne pense pas qu'ils soient corrompus car cela fonctionnait avec un labyrinthe 10k * 10k (image 20k * 20k) et il n'a pas réussi à ouvrir, avec le même code, un labyrinthe de 13k * 13k (image 26k * 26k).

Voici donc le code (j'utilise EasyBMP lib):

int    main() 
{ 
    HandyMaze   labz(MAZE_SIDE, MAZE_SIDE); // Maze generator 
    Labz*    l;       // Maze iteself 
    BMP    img; 

    if (labz.Generate() == false) 
    { 
     std::cout << "Derp" << std::endl; 
     return (1); 
    } 
    l = labz.GetFormatedLab(); 
    if (l == 0) 
    { 
     std::cout << "Dorp" << std::endl; 
     return (1); 
    } 
    std::cout << "Generated" << std::endl; 
    std::cout << "Creating Image ..." << std::endl; 
    img.SetSize(l->w, l->h); 
    if (img.SetBitDepth(1) == false) 
    { 
    std::cout << "Failed to change Depth" << std::endl; 
    return (1); 
    } 
    std::cout << "Filling Image ..." << std::endl; 
    std::cout << l->w << " " << l->h << std::endl; 
    for (int i = 0; i < l->w; ++i) 
    for (int j = 0; j < l->h; ++j) 
     { 
     if (l->lab[j][i] == WALL) 
     { 
     img(j, i)->Red = 0; 
     img(j, i)->Green = 0; 
     img(j, i)->Blue = 0; 
     img(j, i)->Alpha = 0; 
     } 
     else 
     { 
     img(j, i)->Red = 255; 
     img(j, i)->Green = 255; 
     img(j, i)->Blue = 255; 
     img(j, i)->Alpha = 0; 
     } 
     } 
    std::cout << "Saving Image ..." << std::endl; 
    std::stringstream ss; 
    ss << "Laby-" << MAZE_SIDE << ".bmp"; 
    img.WriteToFile(ss.str().c_str()); 
    return (0); 
} 

Comme vous pouvez le voir, le code de dessin est vraiment simple mais quand même ... Est-ce que je manque quelque chose ou que je tente de faire quelque chose que je ne peux pas faire xD?

Merci d'avance pour vos suggestions. PS: La première fois que je poste ici, j'ai essayé d'être aussi clair que possible, mais dites-moi si j'ai fait quelque chose dans le mauvais sens.

Rel4X

+0

Je crois que les fichiers BMP doivent avoir un en-tête (http://en.wikipedia.org/wiki/BMP_file_format#File_structure) – braindf

+0

Salut cerveau. Oui et il me semble que mes tailles sont bien en deçà de la taille maximale: L'en-tête dit 4 octets pour la hauteur et la largeur et la taille totale. 4 octets signés est quelque chose comme 2000000000 pixels. J'ai 1369000000 pixels. –

+0

Essayez les paramètres du canal alpha à 255. –

Répondre

0

Je ne sais pas grand-chose au sujet du problème avec l'utilisation easybmp lib, mais vous pouvez également essayer d'utiliser libpng.

Vous pouvez vérifier le code ci-dessous (en utilisant libpng) pour écrire un plus grand fichier d'image de dimension aussi la libpng produit beaucoup de fichier compressé. Vous pouvez modifier le code selon vos besoins. J'espère que cela aide.

/*********************************************************** 
This is a modification of the original code taken from 
http://www.lemoda.net/c/write-png/ 
***********************************************************/ 

#include "png.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 

/* A coloured pixel. */ 

typedef struct { 
    char color; 
} pixel_t; 

/* A picture. */ 

typedef struct { 
    pixel_t *pixels; 
    size_t width; 
    size_t height; 
} bitmap_t; 

/* Given "bitmap", this returns the pixel of bitmap at the point 
    ("x", "y"). */ 

static pixel_t * pixel_at (bitmap_t * bitmap, int x, int y) 
{ 
    return bitmap->pixels + bitmap->width * y + x; 
} 

/* Write "bitmap" to a PNG file specified by "path"; returns 0 on 
    success, non-zero on error. */ 

static int save_png_to_file (bitmap_t *bitmap, const char *path) 
{ 
    FILE * fp; 
    png_structp png_ptr = NULL; 
    png_infop info_ptr = NULL; 
    size_t x, y; 
    png_byte ** row_pointers = NULL; 
    png_byte *row = NULL; 
    /* "status" contains the return value of this function. At first 
     it is set to a value which means 'failure'. When the routine 
     has finished its work, it is set to a value which means 
     'success'. */ 
    int status = -1; 
    /* The following number is set by trial and error only. I cannot 
     see where it it is documented in the libpng manual. 
    */ 
    int pixel_size = 1; 
    int depth = 8; 

    fp = fopen (path, "wb"); 
    if (! fp) { 
     goto fopen_failed; 
    } 

    png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 
    if (png_ptr == NULL) { 
     goto png_create_write_struct_failed; 
    } 

    info_ptr = png_create_info_struct (png_ptr); 
    if (info_ptr == NULL) { 
     goto png_create_info_struct_failed; 
    } 

    /* Set up error handling. */ 

    if (setjmp (png_jmpbuf (png_ptr))) { 
     goto png_failure; 
    } 

    /* Set image attributes. */ 

    png_set_IHDR (png_ptr, 
        info_ptr, 
        bitmap->width, 
        bitmap->height, 
        depth, 
        PNG_COLOR_TYPE_GRAY, 
        PNG_INTERLACE_NONE, 
        PNG_COMPRESSION_TYPE_DEFAULT, 
        PNG_FILTER_TYPE_DEFAULT); 

    /* Initialize rows of PNG. */ 
    printf("Filling image...\n"); 
    png_init_io (png_ptr, fp); 
    png_write_info(png_ptr, info_ptr); 

    row_pointers = png_malloc (png_ptr, sizeof (pixel_t *)); 
    row = png_malloc (png_ptr, sizeof (pixel_t) * bitmap->width * pixel_size); 
    for (y = 0; y < bitmap->height; ++y) { 
     for (x = 0; x < bitmap->width; ++x) { 
      pixel_t * pixel = pixel_at (bitmap, x, y); 
      row[x-1] = pixel->color; 
     } 
     png_write_row(png_ptr, row); 
    } 
    png_free (png_ptr, row_pointers); 

    /* Write the image data to "fp". */ 
    printf("Writing image...\n"); 
    png_write_end(png_ptr, info_ptr); 

    /* The routine has successfully written the file, so we set 
     "status" to a value which indicates success. */ 

    status = 0; 
    /* 
    for (y = 0; y < bitmap->height; y++) { 
     png_free (png_ptr, row_pointers[y]); 
    } 
    png_free (png_ptr, row_pointers); 
    */ 
png_failure: 
png_create_info_struct_failed: 
    png_destroy_write_struct (&png_ptr, &info_ptr); 
png_create_write_struct_failed: 
    fclose (fp); 
fopen_failed: 
    return status; 
} 

/* Given "value" and "max", the maximum value which we expect "value" 
    to take, this returns an integer between 0 and 255 proportional to 
    "value" divided by "max". */ 

static int pix (int value, int max) 
{ 
    if (value < 0) 
     return 0; 
    return (int) (256.0 *((double) (value)/(double) max)); 
} 

int main() 
{ 
    bitmap_t fruit; 
    int x; 
    int y; 

    /* Create an image. */ 

    fruit.width = 37000; 
    fruit.height = 37000; 

    fruit.pixels = calloc (sizeof (pixel_t), fruit.width * fruit.height); 
    printf("creating image...\n"); 
    for (y = 0; y < fruit.height; y++) { 
     for (x = 0; x < fruit.width; x++) { 
      pixel_t * pixel = pixel_at (& fruit, x, y); 
      if((x+y)%2) 
      { 
       pixel->color = 0; 
      } 
      else 
      { 
       pixel->color = 255; 
      } 
     } 
    } 

    /* Write the image to a file 'fruit.png'. */ 

    save_png_to_file (& fruit, "fruit.png"); 

    return 0; 
} 
+0

Merci a beaucoup, je vais essayer! ... Toujours coincé avec ça, je passe un très mauvais moment xD // –

Questions connexes