C++:读取位图图像的问题
Posted
技术标签:
【中文标题】C++:读取位图图像的问题【英文标题】:C++: problems reading a Bitmap image 【发布时间】:2018-02-18 15:02:47 【问题描述】:我目前正在编写一个处理 512x512 .BMP 图像的函数,我正在努力读取像素数据。我在其中包含 fstream 来处理读取图像数据。
我的函数应该明确适用于 8 位灰度 .BMP 图像,所以我真的不需要担心文件标题。您可以在我的代码中看到我只是将整个标头读入一个数组以供以后使用。
这是我的图像类的构造函数:
// Constructor
Image::Image(const char* inFileName)
// First we will initialize our Image Data Arrays:
ImageData = new int* [SIZE];
complexImageData = new complex<double>* [SIZE];
for(int i=0; i<SIZE; ++i)
ImageData[i] = new int [SIZE];
complexImageData[i] = new complex<double> [SIZE];
// Now we will initialize our I/O Files.
outFile = new ofstream;
inFile = new ifstream;
// And now we will fill our data arrays with the input file data.
inFile->open(inFileName,ios::in | ios::binary); // Reads file as binary
inFile->seekg(0,ios::beg); // sets filter position to beginning
inFile->read(header,HEADERSIZE); // Reads header
// Now to read in the image data:
for(int i=0; i<SIZE; ++i)
inFile->read(reinterpret_cast<char*>(ImageData[i]),SIZE);
for(int j=0; j<SIZE; ++j)
cout << ImageData[i][j] << ' ';
cout << endl;
inFile->close();
如您所见,它会在读取数据时打印出数据。这个构造函数的输出对我来说很奇怪。这是读入 ImageData 数组的前 512 个条目:
236854814 237117986 505286158 236854814 505290270 236854814 572662306 237112866 571346462 505290254 505288222 371072534 236328478 504763918 370546198 152442390 503911958 236330518 370546198 152439062 369690902 504763926 236852758 571347470 572662306 571351570 235802142 504237582 505290254 236330526 504241694 235802126 505290262 370546206 370548246 504765974 371070494 505288214 371072534 369694230 235806222 236854814 237117986 235802146 370548254 369690902 504763926 371072534 370546198 152442390 504760598 504763926 237117986 304226850 235802146 235802126 235807246 504241678 504761870 504237590 371072542 370548246 504763926 236854806 235802142 235802126 235802126 504242702 235802126 303178258 505286178 571351566 572662286 572658210 236065314 303178254 571609618 571351586 571613730 571351586 237112866 571351566 303702562 572658210 237112846 304222754 303700506 304226850 168434194 471079956 169088010 169088020 437914122 437918234 169085466 436865546 169482778 336204810 168430100 336857610 336862228 336204820 471077898 471866380 471079964 169090076 203168778 169088012 471077914 336862236 168430090 168434186 168434202 437918234 169482778 168430106 168430106 169482762 336206346 169085450 336206356 135796768 404228120 270014488 303698458 303174162 303174162 404752922 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
如您所见,该数据的大约后半部分全为零。另一行更陌生:
236852766 571346446 236850702 371072542 505291278 371070494 504763934 236330518 370548238 503911966 236852758 371072542 504763913 504237582 571350542 235802126 504242722 503911958 152966678 370542870 369694230 369690905 236330505 504237590 370548246 504763926 370546206 370546198 370546198 235806230 371073550 504763926 370548254 572658206 235807246 571346446 504237582 236854798 505553422 370548254 152442390 236852758 572662306 504765986 370546198 369694217 504763926 370548246 504241686 371072526 235804190 504765974 370542870 151587081 152635673 504763913 369690902 370546206 152443145 505290262 236852766 371072534 505284886 370546206 572397078 371072526 504237598 370548254 371070486 371073566 152439049 370542870 152442377 504763926 571350558 505286174 504765982 236854814 235806238 235802126 235807246 572399134 571351566 571613730 571611666 303698466 437916186 169478682 168430090 169089546 336862236 336860180 336204810 336857620 336202260 168432660 168430090 168430106 471075338 203431964 470551564 336202250 336860180 336860180 336862228 336204820 168430100 436865562 337384458 436868106 168430090 168430090 336204820 436865546 168430090 168432650 269487114 135796760 202905624 437918226 437918234 403705868 404232208 269490200 337252884 571613722 304222738 269228562 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 181497 53543152 0 53543152 0 57016416 0 57016416 0 57135104 0 925696 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
您可以看到它也有相同的零,但在这些零中是一些意想不到的非零条目。 input image 肯定不会出现这种情况。
任何帮助将不胜感激!很抱歉,如果这是重复的,但在发布之前我非常努力地找到了我的问题的答案!
编辑:
我立即注意到正在打印的数字(236854814、237117986 等)不在 8 位范围内。我觉得这很令人困惑,因为我正在读取重新解释为 char 的数据,它在我的系统上是 8 位的。读入整数数组的数据不是应该是8位的吗?我什至尝试制作 __int8** 类型的 ImageData 数组,以便每个条目只能存储 8 位,但它仍然无法正常工作。
【问题讨论】:
【参考方案1】:您的图像是 8bpp 灰度,但您将其读入块 int [SIZE]
(在此过程中提供了错误的缓冲区大小)可能在每个 int
中存储 4 个像素值。如果图像是 8bpp,您可以使用 uint8_t
缓冲区。您还应该执行标头验证(因为现在您可能在错误的位置读取)并检查读取的实际字节数。根据图像类型/大小,您可能还需要检查每一行的填充。
【讨论】:
好的,你已经解决了我的阅读问题,但在我程序的另一个领域,我遇到了另一个问题!我编写的输出似乎已转换为 8 位颜色 .BMP - 我是否错过了标题中的某些内容?我不是把所有的细节都复制过来了吗?如果是这样,我该怎么做? @FloydEverest 你应该问另一个问题,显示写部分的相关代码。我不知道你是否在你的标题中遗漏了一些东西,因为你还没有发布它。 没关系,我在更广泛的图像集上测试了我的程序,结果发现我正在处理 BMP 文件的异常标头。再次感谢您的帮助!以上是关于C++:读取位图图像的问题的主要内容,如果未能解决你的问题,请参考以下文章