参考:http://zhidao.baidu.com/link?url=K0X3GJIiAdhEJ3UheJ8RTcEKrApKn2B6dRkcEpkVspNfebrm345Ltx7_VUJqDs9QYA-0MOTBMBLcOm-h_MD7sa
参考:http://blog.csdn.net/lanbing510/article/details/8176231
最近要看看自己生成的图像,想输出到一个bmp文件。
1、BMP文件概述
BMP(Bitmap-File)图形文件,又叫位图文件,是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各图像绘制操作都是以BMP为基础的。一个BMP文件由四部分组成:
- 位图文件头
- 位图信息段
- 调色板
- 位图数据
一个BMP文件,可以用代码表示,如下:
typedef struct tagBITMAP_FILE{ BITMAPFILEHEADER bitmapheader; BITMAPINFOHEADER bitmapinfoheader; PALETTEENTRY palette[256]; UCHAR *buffer; } BITMAP_FILE;
二、BMP文件的写入
将一个32位数据写入到BMP。
#pragma pack(2)//必须得写,否则sizeof得不到正确的结果 typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; typedef long LONG; typedef struct { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER; typedef struct { DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; void saveBitmap(int w, int h,unsigned char *pData,int nDatasize ) { // Define BMP Size const int height = w; const int width = h; const int size = nDatasize; double x, y; int index; // Part.1 Create Bitmap File Header BITMAPFILEHEADER fileHeader; fileHeader.bfType = 0x4D42; fileHeader.bfReserved1 = 0; fileHeader.bfReserved2 = 0; fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + size; fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // Part.2 Create Bitmap Info Header BITMAPINFOHEADER bitmapHeader = { 0 }; bitmapHeader.biSize = sizeof(BITMAPINFOHEADER); bitmapHeader.biHeight = -height; bitmapHeader.biWidth = width; bitmapHeader.biPlanes = 1; bitmapHeader.biBitCount = 32; bitmapHeader.biSizeImage = size; bitmapHeader.biCompression = 0; //BI_RGB // Write to file FILE *output = fopen("output.bmp", "wb"); if (output == NULL) { printf("Cannot open file!\n"); } else { fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, output); fwrite(&bitmapHeader, sizeof(BITMAPINFOHEADER), 1, output); fwrite(pData, size, 1, output); fclose(output); } }
#pragma pack(2)必须要加。bfType是2个字节,对应“BM”,后4个字节是文件大小,又对应4字节。如果不设定对齐方式,而按默认的8字节或4字节对应,这些属性就错位了,而别人又是按标准来读取的,对齐方式不同,自然出错。一般情况下的编程之所以不考虑这些问题,是因为读取和保存都是你个人完成的,对齐方式是一样的,自然不出错。而这里你生成的图片可能还要供别人使用,自然要严格遵守标准。
将一个正弦曲线写入24位的BMP。
void saveBitmap() { // Define BMP Size const int height = 600; const int width = 800; const int size = height * width * 3; double x, y; int index; // Part.1 Create Bitmap File Header BITMAPFILEHEADER fileHeader; fileHeader.bfType = 0x4D42; fileHeader.bfReserved1 = 0; fileHeader.bfReserved2 = 0; fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + size; fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // Part.2 Create Bitmap Info Header BITMAPINFOHEADER bitmapHeader = { 0 }; bitmapHeader.biSize = sizeof(BITMAPINFOHEADER); bitmapHeader.biHeight = height; bitmapHeader.biWidth = width; bitmapHeader.biPlanes = 3; bitmapHeader.biBitCount = 24; bitmapHeader.biSizeImage = size; bitmapHeader.biCompression = 0; //BI_RGB // Part.3 Create Data BYTE *bits = (BYTE *)malloc(size); // Clear memset(bits, 0xFF, size); // Sin Graph for (x = 0; x < 800; x += 0.5) { y = sin(x / 100.0) * 200 + 300; index = (int)y * 800 * 3 + (int)x * 3; bits[index + 0] = 255; // Blue bits[index + 1] = 0; // Green bits[index + 2] = 0; // Red } // Write to file FILE *output = fopen("output.bmp", "wb"); if (output == NULL) { printf("Cannot open file!\n"); } else { fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, output); fwrite(&bitmapHeader, sizeof(BITMAPINFOHEADER), 1, output); fwrite(bits, size, 1, output); fclose(output); } }
注意点:
图象的高度,以象素为单位。这个值除了用于描述图像的高度之外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明图像是倒向的,即:数据的第一行其实是图像的最后一行,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也就是时,高度值是一个正数。
时间: 2024-10-11 13:09:30