我正在尝试查找文件大小,文件头大小宽度和bmp文件的高度。我研究了bmp文件的格式和文件中的字节排列。 当我尝试此代码时,它显示不同文件的错误宽度和高度。 到目前为止,我已经尝试了三张图片。这一个图像可以产生正确的测量结果。
这个没有:
我不明白我哪里出错了,但是比特深度显示了所有三张图片的正确值。
这是我的代码:
#include<iostream>
#include<fstream>
#include<math.h>
using namespace std;
int main() {
ifstream inputfile("bmp.bmp",ios::binary);
char c; int imageheader[1024];
double filesize=0; int width=0; int height=0;int bitCount = 0;
for(int i=0; i<1024; i++) {
inputfile.get(c); imageheader[i]=int(c);
}
filesize=filesize+(imageheader[2])*pow(2,0)+(imageheader[3])*pow(2,8)+(imageheader[4])*pow(2,16)+(imageheader[5])*pow(2,24);
cout<<endl<<endl<<"File Size: "<<(filesize/1024)<<" Kilo Bytes"<<endl;
width=width+(imageheader[18])*pow(2,0)+(imageheader[19])*pow(2,8)+(imageheader[20])*pow(2,16)+(imageheader[21])*pow(2,24);
cout<<endl<<"Width: "<<endl<<(width)<<endl;
height=height+(imageheader[22])*pow(2,0)+(imageheader[23])*pow(2,8)+(imageheader[24])*pow(2,16)+(imageheader[25])*pow(2,24);
cout<<endl<<"Height: "<<endl<<(height)<<endl;
bitCount=bitCount+(imageheader[28])*pow(2,0)+(imageheader[29])*pow(2,8);
cout<<endl<<"Bit Depth: "<<endl<<(bitCount)<<endl;
}
答案 0 :(得分:2)
让我们从一系列字节读取BMP头开始,而不是整数。为了使此代码真正可移植,我们将使用<stdint>
类型。
#include <fstream>
#include <stdint.h>
int main()
{
ifstream inputfile("D:/test.bmp", ios::binary);
uint8_t headerbytes[54] = {};
inputfile.read((char*)headerbytes, sizeof(headerbytes));
现在我们已经将内存中的标头作为字节数组,我们可以简单地将每个标头字段的内存地址转换回整数。引用wikipedia page代表bmp和the layout diagram。
uint32_t filesize = *(uint32_t*)(headerbytes+2);
uint32_t dibheadersize = *(uint32_t*)(headerbytes + 14);
uint32_t width = *(uint32_t*)(headerbytes + 18);
uint32_t height = *(uint32_t*)(headerbytes + 22);
uint16_t planes = *(uint16_t*)(headerbytes + 26);
uint16_t bitcount = *(uint16_t*)(headerbytes + 28);
现在,该代码的精明读者将认识到BMP头的各个部分以小端格式存储。并且上面的代码依赖于您拥有x86处理器或字节布局为Little Endian的任何其他架构。在大端机器上,您必须为上面的每个变量应用一个变换方法,从LE转换为BE。
答案 1 :(得分:0)
该错误正在读取已签名的字符。这应该解决它:
for(int i = 0; i < 1024; i++)
{
//inputfile.get(c); imageheader[i] = int(c);
// This version of get returns int, where -1 means EOF. Should be checking for errors...
imageheader[i] = inputfile.get();
}
其他人评论了对代码的改进,所以我不会打扰。