编写BMP文件(独立于平台)

时间:2010-06-30 16:11:12

标签: bmp

我有一个像

这样的结构
   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 个答案:

答案 0 :(得分:1)

看看:

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

写出标题,调色板和数据。

编写位图数据时要小心。这是“倒置” - 数据中的第一个像素是左下角像素。

答案 1 :(得分:1)

首先声明您将主要使用的三种类型的初始值设定项:

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;

然后您可以通过多种方式操作图像。您可以创建一维/二维数组来包含数据或直接操作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()直接写入像素。