Creating a BMP file (bitmap) in C

前端 未结 3 378
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-14 02:48

I\'m trying to make a bitmap in C, just from code. I\'m currently trying to make a very easy .bmp image, with a height of 1px and a width of 4 pixels, with all white pixels.

相关标签:
3条回答
  • 2020-12-14 03:22

    Open your file with a hex editor to see what is actually there. This will help you determine if your code is doing something unexpected.

    0 讨论(0)
  • 2020-12-14 03:23

    Here is the code tested on linux.

    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>
    #include <malloc.h>
    #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);
    }
    
    0 讨论(0)
  • 2020-12-14 03:31

    Your pixel offset (bytes 10..13) is zero, but the pixel data don't actually start at the beginning of the file, they start at byte 54.

    Also:

    • Your comment on byte 34 says "bits" but means "bytes", but of course that doesn't matter.

    • Your horizontal and vertical resolutions have the wrong byte order, but I very much doubt that that matters.

    If I were doing this I'd define structs for the header data (indeed, if you're on Windows, Microsoft have already done this) and use a macro or something for putting bytes into the right order portably.

    Whether you "have to reverse the order of the bytes" depends on the endianity of the processor you're using. Writing separate bytes separately, as you're doing, is an effective way to avoid having to worry about this.

    0 讨论(0)
提交回复
热议问题