/* * Author: Leng_que * Date: 2010年1月31日20:46:44 * E-mail: leng_que@yahoo.com.cn * Description: 一个生成位图的演示程序 */ #include <windows.h> #include <stdio.h> #include <time.h> #pragma pack(2) typedef struct { WORD bfType; //位图文件的类型,必须为BM(0-1字节) DWORD bfSize; //位图文件的大小,以字节为单位(2-5字节) WORD bfReserved1; //位图文件保留字,必须为0(6-7字节) WORD bfReserved2; //位图文件保留字,必须为0(8-9字节) DWORD bfOffBits; //位图数据的起始位置,以相对于位图(10-13字节) //文件头的偏移量表示,以字节为单位 } FileHead; #pragma pack() //BITMAPFILEHEADER typedef struct { DWORD biSize; //本结构所占用字节数(14-17字节) LONG biWidth; //位图的宽度,以像素为单位(18-21字节) LONG biHeight; //位图的高度,以像素为单位(22-25字节) WORD biPlanes; //目标设备的级别,必须为1(26-27字节) WORD biBitCount; //每个像素所需的位数,必须是1(双色),(28-29字节) //4(16色),8(256色)或24(真彩色)之一 DWORD biCompression; //位图压缩类型,必须是 0(不压缩),(30-33字节) //1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 DWORD biSizeImage; //位图的大小,以字节为单位(34-37字节) LONG biXPelsPerMeter; //位图水平分辨率,每米像素数(38-41字节) LONG biYPelsPerMeter; //位图垂直分辨率,每米像素数(42-45字节) DWORD biClrUsed; //位图实际使用的颜色表中的颜色数(46-49字节) DWORD biClrImportant; //位图显示过程中重要的颜色数(50-53字节) } InfoHead; //BITMAPINFOHEADER typedef struct { BYTE rgbBlue; //蓝色的亮度(值范围为0-255) BYTE rgbGreen; //绿色的亮度(值范围为0-255) BYTE rgbRed; //红色的亮度(值范围为0-255) } RGB_data; int bitmapCreator(char *filename, int width, int height, unsigned char *data) { bool fHaveZero=false; unsigned short ZeroCount=0; DWORD biSizeImage=0; if ( (width*3)%4==0 ) { biSizeImage = width*height*3; } else { for ( int n=1; n<=3; n++ ) { if ( (width*3+n)%4 == 0 ) { biSizeImage = width*height*3 + n*height; ZeroCount = n; fHaveZero = true; break; } } } FileHead bmp_head; bmp_head.bfType = 0x4D42; bmp_head.bfSize = (biSizeImage+0x36); bmp_head.bfReserved1 = 0; bmp_head.bfReserved2 = 0; bmp_head.bfOffBits = 0x36; HDC hDC = GetDC(NULL); InfoHead bmp_info; bmp_info.biSize = 0x28; bmp_info.biWidth = width; bmp_info.biHeight = height; bmp_info.biPlanes = 1; bmp_info.biBitCount = 24; bmp_info.biCompression = 0; bmp_info.biSizeImage = biSizeImage; bmp_info.biXPelsPerMeter = GetDeviceCaps(hDC,HORZRES)*1000/GetDeviceCaps(hDC,HORZSIZE); bmp_info.biYPelsPerMeter = GetDeviceCaps(hDC,VERTRES)*1000/GetDeviceCaps(hDC,VERTSIZE); bmp_info.biClrUsed = 0; bmp_info.biClrImportant = 0; unsigned char *pData = new unsigned char[bmp_head.bfSize]; memcpy((void*)pData, (void*)&bmp_head, sizeof(FileHead)); memcpy((void*)(pData+sizeof(FileHead)), (void*)&bmp_info, sizeof(InfoHead)); if ( !fHaveZero ) { memcpy((void*)(pData+0x36), (void*)data, biSizeImage); } else { int line = width*3+ZeroCount; for ( int count=0; count<height; count++ ) { memcpy((void*)(pData+0x36+count*line), (void*)(data+count*width*3), width*3); memset((void*)(pData+0x36+count*line+width*3), 0, ZeroCount); } } FILE *fp=NULL; fp = fopen(filename, "wb"); if ( fp==NULL ) { return -1; } fwrite(pData, 1, bmp_head.bfSize, fp); fclose(fp); fp = NULL; delete[] pData; pData = NULL; return 0; } int main(void) { enum { width=99, height=99 }; RGB_data buffer[height][width]; memset(buffer, 0, sizeof(buffer)); srand(time(0)); int i=0; int j=0; for (i=0; i<height; i++) { for (j=0; j<width; j++) { buffer[i][j].rgbBlue = rand()%256; buffer[i][j].rgbGreen = rand()%256; buffer[i][j].rgbRed = rand()%256; } } bitmapCreator(".//demo.bmp", width, height, (unsigned char *)buffer); return 0; }