Написание файлов BMP (Независимая от платформы) - PullRequest
2 голосов
/ 30 июня 2010

У меня есть такая структура, как

   typedef struct  FT_Bitmap_
  {
    int             rows;
    int             width;
    int             pitch;
    unsigned char*  buffer;
    short           num_grays;
    char            pixel_mode;
    char            palette_mode;
    void*           palette;

  } FT_Bitmap;

определение моих растровых данных

Я хочу создать действительный bmp-файл из этой структуры. Как я могу это сделать?

Ответы [ 2 ]

1 голос
/ 01 июня 2014

Сначала объявите три типа инициализаторов, которые вы будете в основном использовать:

typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;

Что касается структур, я предлагаю вам использовать три, каждый для элемента BMP:

typedef struct BITMAPINFOHEADER
{
    dword bmp_size;
    word bmp_app1;
    word bmp_app2;
    dword bmp_offset;
} BMP;

typedef struct DIB_HEADER
{
    dword dib_size;
    dword dib_w;
    dword dib_h;
    word dib_planes;
    word dib_bits;
    dword dib_compression;
    dword dib_rawsize;
    dword dib_xres;
    dword dib_yres;
    dword dib_palette;
    dword dib_important;
} DIB;

typedef struct PIXEL_ARRAY
{
    byte B;
    byte G;
    byte R;
} PIX;

Тогда вы можете манипулировать изображением разными способами.Вы можете создать 1D / 2D массив для хранения данных или просто манипулировать bmp напрямую.Следующий код создает 500x460 цветных пустых bmp напрямую:

void new (char NAME[] , byte RED , byte GREEN , byte BLUE)
{
    char build_name[256];
    const char* id = "BM";
    int i, j;
    char debug[128];

    FILE* fp;

    dword rsize = (500 * sizeof(PIX) + 3) / 4 * 4;
    dword pad = rsize - 500 * sizeof(PIX);
    dword rawsize = rsize * 460 * sizeof(PIX);
    byte zero[3] = {0};

    dword size      = (2) + sizeof(BMP) + sizeof(DIB) + sizeof(PIX);

    BMP bmp[] = { 2+sizeof(BMP)+sizeof(DIB)+(sizeof(rawsize)/4), 0, 0, 2+sizeof(BMP)+sizeof(DIB) }; //2+ [!]
    DIB dib[] = { sizeof(DIB), 500, 460, 1, 24, 0, (sizeof(rawsize)/4), 2835, 2835, 0, 0 };
    PIX pix;
    pix.R = RED;
    pix.G = GREEN;
    pix.B = BLUE;

    sprintf(build_name, "%s.bmp", NAME);
    fp = fopen(build_name, "wb");
    if(!fp) strcpy(debug, "Access Denied.");
    else strcpy(debug, "Saved.");

    fwrite(id, 1, 2, fp);
    fwrite(&bmp, 1, sizeof(bmp), fp);
    fwrite(&dib, 1, sizeof(dib), fp);

    for(i = 0; i < 460; i++)
    {
        for(j = 0; j < 500; j++)
        {
            fwrite(&pix, sizeof(pix), 1, fp);
        }
        if (pad) fwrite(zero, 1, pad, fp);
    }

    fclose(fp);
}

Точка использует fseek() для определения местоположения пикселя и fwrite() для прямой записи пикселей.

1 голос
/ 30 июня 2010

Взгляните на:

http://en.wikipedia.org/wiki/BMP_file_format

Запишите заголовок, палитру и данные.

Просто будьте осторожны при записи растровых данных. Это «вверх ногами» - первый пиксель в данных - это пиксель в левом нижнем углу.

...