创建大图像

时间:2014-09-04 17:13:23

标签: c++ c image bitmap

首先,你好!

然后,一点上下文:

我实际上在制作一个“迷宫发生器”。我现在可以生成18500宽度和18500高度的迷宫(这让我很开心!)。

所以,这一代没问题。

然后,当然,我想将它们写入.jpeg / .bmp或其他文件。

所以,对于一个18k5 * 18k5的迷宫,我需要一张37k * 37k的图像。

我首先尝试使用.jpeg。它工作正常,但输出文件大1.2千兆字节。那些花了太多时间太开放......但我可以打开它们。

所以我尝试使用BMP格式,因为它允许每个1位编码像素。输出文件现在实际上更小......但是我无法打开它们......我被告知文件“已损坏或太大”。

我不认为它们已被破坏,因为它使用了10k * 10k迷宫(20k * 20k图像)并且无法打开,使用相同的代码,一个13k * 13k的迷宫(26k * 26k图像)。

所以这是代码(我正在使用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);
}

正如你所看到的,绘图代码非常简单,但仍然......我错过了一些东西,还是我想做一些我不能做xD的事情?

提前感谢您的建议。

PS:第一次在这里发帖,我试着尽可能清楚,但告诉我是否做错了。

Rel4X

1 个答案:

答案 0 :(得分:0)

我对使用easybmp lib的问题了解不多,但您也可以尝试使用libpng。

您可以检查以下代码(使用libpng)来编写更大的维度图像文件,libpng也会生成大量压缩文件。您可以根据需要修改代码。希望它有所帮助。

/***********************************************************
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;
}