Created
March 7, 2013 06:43
-
-
Save chenzx/5106010 to your computer and use it in GitHub Desktop.
Save memory bitmap data into a .bmp file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //typedef's to adapter to struct BMP_FILEHDR & BMP_INFOHDR; | |
| typedef unsigned char UINT8; | |
| typedef signed char SINT8; | |
| typedef unsigned short UINT16; | |
| typedef signed short SINT16; | |
| typedef unsigned int UINT32; | |
| typedef signed int SINT32; | |
| //struct BMP_FILEHDR & BMP_INFOHDR defines are copied from Win32 .h files; | |
| struct BMP_FILEHDR // BMP file header | |
| { | |
| UINT32 bfSize; // size of file | |
| UINT16 bfReserved1; | |
| UINT16 bfReserved2; | |
| UINT32 bfOffBits; // pointer to the pixmap bits | |
| }; | |
| struct BMP_INFOHDR // BMP information header | |
| { | |
| UINT32 biSize; // size of this struct | |
| UINT32 biWidth; // pixmap width | |
| UINT32 biHeight; // pixmap height | |
| UINT16 biPlanes; // should be 1 | |
| UINT16 biBitCount; // number of bits per pixel | |
| UINT32 biCompression; // compression method | |
| UINT32 biSizeImage; // size of image | |
| UINT32 biXPelsPerMeter; // horizontal resolution | |
| UINT32 biYPelsPerMeter; // vertical resolution | |
| UINT32 biClrUsed; // number of colors used | |
| UINT32 biClrImportant; // number of important colors | |
| }; | |
| #define BitmapColorGetA(color) (((color) >> 24) & 0xFF) | |
| #define BitmapColorGetR(color) (((color) >> 16) & 0xFF) | |
| #define BitmapColorGetG(color) (((color) >> 8) & 0xFF) | |
| #define BitmapColorGetB(color) (((color) >> 0) & 0xFF) | |
| //当前以result.bmp输出,忽略img_path参数!! | |
| int saveToBMPFile(char* img_data, int width, int height, int stride, const char* img_path){ | |
| //Normally, width*4 == stride | |
| //virtual PixelFormat& GetPixelFormat() =0; //assume pf is ARGB; | |
| FILE* fp = fopen(img_path, "wb"); | |
| if(!fp){ | |
| printf("fopen error!\n"); | |
| return -1; | |
| } | |
| SINT32 bpl=width*4; | |
| // BMP file header. | |
| BMP_FILEHDR fhdr; | |
| fputc('B', fp); | |
| fputc('M', fp); | |
| fhdr.bfReserved1=fhdr.bfReserved2=0; | |
| fhdr.bfOffBits=14+40; // File header size + header size. | |
| fhdr.bfSize=fhdr.bfOffBits+bpl*height; | |
| fwrite(&fhdr, 1, 12, fp); | |
| // BMP header. | |
| BMP_INFOHDR bhdr; | |
| bhdr.biSize=40; | |
| bhdr.biBitCount=32; | |
| bhdr.biCompression=0; // RGB Format. | |
| bhdr.biPlanes=1; | |
| bhdr.biWidth=bmpWidth; | |
| bhdr.biHeight=height; | |
| bhdr.biClrImportant=0; | |
| bhdr.biClrUsed=0; | |
| bhdr.biXPelsPerMeter=2384; | |
| bhdr.biYPelsPerMeter=2384; | |
| bhdr.biSizeImage=bpl*height; | |
| fwrite(&bhdr, 1, 40, fp); | |
| // BMP data. | |
| //for(UINT32 y=0; y<m_height; y++) | |
| for(SINT32 y=height-1; y>=0; y--) //I hate this, But BMP file stores data from image's bottom to up; | |
| { | |
| SINT32 base=data+stride; | |
| for(SINT32 x=0; x<(SINT32)width; x++) | |
| { | |
| UINT32 i=base+x*4; | |
| UINT32 pixelData = *(UINT32*)(data + i); | |
| UINT8 b=BitmapColorGetB(pixelData); | |
| UINT8 g=BitmapColorGetG(pixelData); | |
| UINT8 r=BitmapColorGetR(pixelData); | |
| UINT8 a=BitmapColorGetA(pixelData); | |
| r=r*a/255; | |
| g=g*a/255; | |
| b=b*a/255;//BMP does not supper alpha bits; | |
| UINT32 colorData=(a<<24)|(r<<16)|(g<<8)|b;//a bmp pixel in little endian is B、G、R、A | |
| fwrite(&colorData, 4, 1, fp); | |
| } | |
| } | |
| fflush(fp); | |
| fclose(fp); | |
| return 1; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment