以编程方式制作bmp图像

时间:2014-06-26 17:12:42

标签: c++ image bmp

我正在尝试创建自己的类来操作BMP图像..

我从这个简单的代码开始:

所有内容都按照wikepedia link.

中的规定完成

我遇到两个问题:

  1. 当我尝试打开图片时,它会给出错误

    Premature end of file detected
    
  2. 我创建的实际文件超出了两个字节所应的文件大小。

  3. 以下是代码:

    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    struct BMP_Header
    {
        public :
    
        char id[2];
        unsigned int total_image_size;
        short int app_data1,app_data2;
        unsigned int offset;
    };
    
    struct DIB_Header 
    {
        public :
    
        unsigned int dib_header_size;
        int image_width;
        int image_height;
        short int no_colour_planes;
        short int colour_depth;
        unsigned int compression_method;
        unsigned int raw_image_size;
        unsigned int horizontal_resolution;
        unsigned int vertical_resolution;
        unsigned int num_colours_palette;
        unsigned int imp_colours_used;
    };
    
    
    int main ()
    {
        int index=0;
    
        BMP_Header bmp_header;
        DIB_Header dib_header;
        char pixel_array[16];
    
        bmp_header.total_image_size=70;
        bmp_header.offset=54;
        bmp_header.id[0]='B';
        bmp_header.id[1]='M';
        bmp_header.app_data1=0;
        bmp_header.app_data2=0;
    
        dib_header.dib_header_size=40;
        dib_header.image_width=2;
        dib_header.image_height=2;
        dib_header.colour_depth=24;
        dib_header.raw_image_size=16;
        dib_header.horizontal_resolution=2835;
        dib_header.vertical_resolution=2835;
        dib_header.no_colour_planes=1;
        dib_header.compression_method=0;
        dib_header.num_colours_palette=0;   
        dib_header.imp_colours_used=0;
    
        pixel_array[index++]=0;
        pixel_array[index++]=0;
        pixel_array[index++]=255;
    
        pixel_array[index++]=255;
        pixel_array[index++]=255;
        pixel_array[index++]=255;
    
        pixel_array[index++]=0;
        pixel_array[index++]=0;
    
        pixel_array[index++]=255;
        pixel_array[index++]=0;
        pixel_array[index++]=0;
    
        pixel_array[index++]=0;
        pixel_array[index++]=255;
        pixel_array[index++]=0;
    
        pixel_array[index++]=0;
        pixel_array[index++]=0;
    
    // Image Made
        fstream file;
        file.open ("abc.bmp",ios::out | ios::binary);
        file.write ((char*)&bmp_header,sizeof (bmp_header));
        file.write ((char*)&dib_header,sizeof (dib_header));
        file.write ((char*)pixel_array,sizeof (pixel_array));
    
        file.close ();
    return 0;
    }
    

2 个答案:

答案 0 :(得分:3)

您不应该使用C结构来读取/写入BMP标头之类的内容,因为不能保证精确的二进制布局:特别是因为fields alignment and padding。还有一个小大的结束问题,你必须要注意。

解决方法是包含编译器编译指示/设置以禁用结构填充;更好的选择是明确地写每个字段。

补充:更糟糕的是,正如评论所指出的那样,对于固定宽度字段使用C普通类型(int ...)是错误的;实际宽度取决于平台。你应该使用int32_t或类似的东西。

答案 1 :(得分:1)

struct DIB_Header 
{
    public :

    unsigned int dib_header_size;
    int image_width;
    int image_height;
    short int no_colour_planes;
    short int colour_depth;
    unsigned int compression_method;
    unsigned int raw_image_size;
    unsigned int horizontal_resolution;
    unsigned int vertical_resolution;
    unsigned int num_colours_palette;
    unsigned int imp_colours_used;


} __attribute__ ((packed));

这应该消除您报告的填充问题,前提是您的元素是标题的适当大小(我没有交叉检查)。在C / C ++中处理bmp没有问题。 YMMV取决于编译器,因为每个可以稍微不同地处理打包属性。不过在这种情况下你应该是鳍。

另外,请注意BMP文件在数据元素中期望的行填充。根据{{​​3}}的格式指南:

  

表示位图像素的位按行打包。尺寸   每行的四舍五入为4个字节的倍数(32位DWORD)   填充。