我正在尝试创建自己的类来操作BMP图像..
我从这个简单的代码开始:
所有内容都按照wikepedia link.
中的规定完成我遇到两个问题:
当我尝试打开图片时,它会给出错误
Premature end of file detected
我创建的实际文件超出了两个字节所应的文件大小。
以下是代码:
#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;
}
答案 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) 填充。