我正在编写一个程序来为我的化学实验室的一些数据创建图像。我们正在研究元素等的排放,并编写数据以包括通过光谱仪显示频带的示例。我认为编写一个程序来为我做这件事会很整洁,而不是彩色铅笔,所以一切都很整洁。另外,我没有彩色铅笔。
我将图像数据作为 RGB 值存储在一个 int 数组中,长度为我想要的图像的宽度 * 高度,宽度为 320,高度为 50。最后我将它们作为 24 位 BGR 排序写入文件像素。
在将数据写入文件之前,我当然会尝试写入 BMP 标头。MSDN 有一个图表来显示文件部分的一般顺序,其中包括一些关于 RBGQuads 的内容,但在段落解释中没有描述如何使用它们。我认为它们是可选的?我发现这张图表显示了我所期望的标题的唯一强制性部分:http: //www.fastgraph.com/help/bmp_header_format.html,所以我认为我在正确的轨道上。
因此,我开始使用字节顺序,因为在尝试使用 Paint 或在 Windows 图像查看器中打开时,我的文件总是“损坏或损坏”。
所有消息来源都说 BMP 标头是小端的。我尝试在写入时双向交换字节顺序,但仍然无法打开文件。自制损坏文件还有其他常见的罪魁祸首吗?
这是我存储标题信息的地方:
typedef struct
{
char type[2];
unsigned int fsize;
unsigned short res1;
unsigned short res2;
unsigned int data_offset;
} BMPFILEHEADER;
typedef struct
{
unsigned int sizebytes;
int width_pix;
int height_pix; // negative for top down.
unsigned short planes; // must be 1
unsigned short bits_per_pix;
unsigned int compression; // zero for BI_RGB (uncompressed)
unsigned int SizeImage; // may be set to 0 for BI_RGB images.
int pix_per_meter_x;
int pix_per_meter_y;
unsigned int color_used; // set to 0
unsigned int color_important; // set to 0
} BMPINFOHEADER;
当然,我是按这个顺序写的。-- 类型是 char[] 因为无论如何它必须是值 'B' 'M'。
首先我尝试用 fwrite() 编写它们:
fwrite ( &header , 1 , 14 , fhandle );
fwrite ( &headerext , 1 , 40 , fhandle );
然后我试着像这样写它们:
fputc ( 'B' , fhandle );
fputc ( 'M' , fhandle );
fw_little_end ( fhandle , &header.fsize , 4 );
fw_little_end ( fhandle , &header.res1 , 2);
fw_little_end ( fhandle , &header.res2 , 2);
fw_little_end ( fhandle , &header.data_offset , 4);
其中 fw_little_end() 看起来像这样:
void fw_little_end ( FILE * fhandle , void * data , int size )
{
int i;
char * cdata = data;
for ( i = size; i > 0; i-- )
{
fputc ( *(cdata+i-1) , fhandle );
}
}
可能是最初它被写入文件小端并且我的fw_()
函数命名错误,但为了确定,我也从 size-0 和 0-size 尝试过它。
如果听起来相关,这就是写入数据的地方:
int shift1 = 256;
int shift2 = 256*256;
for ( i = 0; i < img_size; i++)
{
fputc ( (unsigned char) (data[i]%256) , fhandle ); // B
fputc ( (unsigned char) (data[i]/shift1)%256 , fhandle ); // G
fputc ( (unsigned char) (data[i]/shift2)%256 , fhandle ); // R
} // theoretically B only needs the typecast, not the %256 but oh well lol.
这篇文章已经很长了,希望我已经包含了足够多的相关代码。我很抱歉,因为我知道那里有很多信息,除此之外对我来说没有任何意义。如果有更好的方式来做这些事情,我很乐意指出正确的方向。
因此,我感谢您的所有意见。