在C中创建BMP文件(位图)

我试图用C代码创建一个位图。 我正在尝试制作一个非常简单的.bmp图像,高度为1像素,宽度为4像素,所有白色像素。 我已阅读格式说明并尝试应用它。 这导致以下代码:

char bitmap[1000]; void BMPmake() { // -- FILE HEADER -- // // bitmap signature bitmap[0] = 'B'; bitmap[1] = 'M'; // file size bitmap[2] = 66; // 40 + 14 + 12 bitmap[3] = 0; bitmap[4] = 0; bitmap[5] = 0; // reserved field (in hex. 00 00 00 00) for(int i = 6; i < 10; i++) bitmap[i] = 0; // offset of pixel data inside the image for(int i = 10; i < 14; i++) bitmap[i] = 0; // -- BITMAP HEADER -- // // header size bitmap[14] = 40; for(int i = 15; i < 18; i++) bitmap[i] = 0; // width of the image bitmap[18] = 4; for(int i = 19; i < 22; i++) bitmap[i] = 0; // height of the image bitmap[22] = 1; for(int i = 23; i < 26; i++) bitmap[i] = 0; // reserved field bitmap[26] = 1; bitmap[27] = 0; // number of bits per pixel bitmap[28] = 24; // 3 byte bitmap[29] = 0; // compression method (no compression here) for(int i = 30; i  4 pixels bitmap[35] = 0; bitmap[36] = 0; bitmap[37] = 0; // horizontal resolution of the image - pixels per meter (2835) bitmap[38] = 0; bitmap[39] = 0; bitmap[40] = 0b00110000; bitmap[41] = 0b10110001; // vertical resolution of the image - pixels per meter (2835) bitmap[42] = 0; bitmap[43] = 0; bitmap[44] = 0b00110000; bitmap[45] = 0b10110001; // color pallette information for(int i = 46; i < 50; i++) bitmap[i] = 0; // number of important colors for(int i = 50; i < 54; i++) bitmap[i] = 0; // -- PIXEL DATA -- // for(int i = 54; i < 66; i++) bitmap[i] = 0; } void BMPwrite() { FILE *file; file = fopen("bitmap.bmp", "w+"); for(int i = 0; i < 66; i++) { fputc(bitmap[i], file); } fclose(file); } 

当我尝试打开此图像时,它表示图像已损坏。 我在这里错过了什么吗?

我还注意到.bmp整数的编码是小端。 我认为这意味着我必须颠倒字节的顺序。 例如,四个字节中的256是:00000000 00000000 00000001 00000000,我认为在小端,这将是:00000000 00000001 00000000 00000000

有人能帮我一把吗? 我使用正确的方法吗? 任何帮助,将不胜感激!

提前致谢!

您的像素偏移量(字节10..13)为零,但像素数据实际上并不是从文件的开头开始,而是从字节54开始。

也:

  • 你对字节34的评论说“比特”,但意思是“字节”,但当然这无关紧要。

  • 您的水平和垂直分辨率具有错误的字节顺序,但我非常怀疑这一点很重要。

如果我这样做,我会为头数据定义结构(事实上,如果你在Windows上,微软已经这样做了)并使用宏或其他东西将字节顺序放入正确的顺序。

是否“必须颠倒字节的顺序”取决于您正在使用的处理器的字节顺序。 分别编写单独的字节,就像你正在做的那样,是避免担心这一点的有效方法。

这是在linux上测试的代码。

 #include  #include  #include  #include  #define _height 600 #define _width 800 #define _bitsperpixel 24 #define _planes 1 #define _compression 0 #define _pixelbytesize _height*_width*_bitsperpixel/8 #define _filesize _pixelbytesize+sizeof(bitmap) #define _xpixelpermeter 0x130B //2835 , 72 DPI #define _ypixelpermeter 0x130B //2835 , 72 DPI #define pixel 0xFF #pragma pack(push,1) typedef struct{ uint8_t signature[2]; uint32_t filesize; uint32_t reserved; uint32_t fileoffset_to_pixelarray; } fileheader; typedef struct{ uint32_t dibheadersize; uint32_t width; uint32_t height; uint16_t planes; uint16_t bitsperpixel; uint32_t compression; uint32_t imagesize; uint32_t ypixelpermeter; uint32_t xpixelpermeter; uint32_t numcolorspallette; uint32_t mostimpcolor; } bitmapinfoheader; typedef struct { fileheader fileheader; bitmapinfoheader bitmapinfoheader; } bitmap; #pragma pack(pop) int main (int argc , char *argv[]) { FILE *fp = fopen("test.bmp","wb"); bitmap *pbitmap = (bitmap*)calloc(1,sizeof(bitmap)); uint8_t *pixelbuffer = (uint8_t*)malloc(_pixelbytesize); strcpy(pbitmap->fileheader.signature,"BM"); pbitmap->fileheader.filesize = _filesize; pbitmap->fileheader.fileoffset_to_pixelarray = sizeof(bitmap); pbitmap->bitmapinfoheader.dibheadersize =sizeof(bitmapinfoheader); pbitmap->bitmapinfoheader.width = _width; pbitmap->bitmapinfoheader.height = _height; pbitmap->bitmapinfoheader.planes = _planes; pbitmap->bitmapinfoheader.bitsperpixel = _bitsperpixel; pbitmap->bitmapinfoheader.compression = _compression; pbitmap->bitmapinfoheader.imagesize = _pixelbytesize; pbitmap->bitmapinfoheader.ypixelpermeter = _ypixelpermeter ; pbitmap->bitmapinfoheader.xpixelpermeter = _xpixelpermeter ; pbitmap->bitmapinfoheader.numcolorspallette = 0; fwrite (pbitmap, 1, sizeof(bitmap),fp); memset(pixelbuffer,pixel,_pixelbytesize); fwrite(pixelbuffer,1,_pixelbytesize,fp); fclose(fp); free(pbitmap); free(pixelbuffer); } 

使用hex编辑器打开文件以查看实际存在的内容。 这将帮助您确定您的代码是否正在执行意外操作。