从 bmp 文件中读取 RGB 像素
Posted
技术标签:
【中文标题】从 bmp 文件中读取 RGB 像素【英文标题】:Reading RGB pixels from bmp file 【发布时间】:2015-12-11 20:21:07 【问题描述】:我有一个小的 bmp 文件,如果 R、G 和 B 不全为零,我想获取每个像素的 RGB 值并将这些值输出到 txt 文件中。我写了以下程序;它正确读取标题数据,但没有出现 RGB 值。我认为我在 for 循环中做错了什么。
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
ifstream ifs;
ofstream ofs;
char input[80];
char output[80];
cout<<"Input file name"<<endl;
cin>>input;
ifs.open(input, ios::binary);
if(!ifs)
cout<<"Error in opening file"<<endl;
system("pause");
return 0;
cout<<"Output file name"<<endl;
cin>>output;
ofs.open(output, ios::binary);
ifs.seekg(2);
int file_size;
ifs.read((char*)&file_size, sizeof(int));
ofs<<"Bitmap size: "<<file_size<<"\r\n";
ifs.seekg(10);
int beg;
ifs.read((char*)&beg, sizeof(int));
ofs<<"Beggining of image: "<<beg<<"\r\n";
ifs.seekg(18);
int columns;
ifs.read((char*)&columns, sizeof(int));
ofs<<"Column number: "<<columns<<"\r\n";
ifs.seekg(22);
int rows;
ifs.read((char*)&rows, sizeof(int));
ofs<<"Row number: "<<rows<<"\r\n";
int image_size=0;
columns+=(3*columns)%4;
image_size=3*columns*rows;
ofs<<"Size of image"<<image_size<<"\r\n";
ifs.seekg(beg);
unsigned char R,G,B;
for(int i=0; i<image_size; i+=3)
ifs.read((char*)&B, sizeof(unsigned char));
ifs.read((char*)&G, sizeof(unsigned char));
ifs.read((char*)&R, sizeof(unsigned char));
if(R!=0 || G!=0 || B!=0)
ofs<<"R: "<<R<<" G: "<<G<<" B: "<<B<<" position in file: "<<ifs.tellg()<<"\r\n";
system("pause");
return 0;
【问题讨论】:
BMP 文件格式比您想象的要复杂得多。使用库而不是滚动您自己的 BMP 导入器。 【参考方案1】:我运行了代码,它运行良好,我想你的意思是“RGB 值没有出现”你没有看到整数值,在这种情况下,这将解决它:
ofs<<"R: "<<int(R)<<" G: "<<int(G)<<" B: "<<int(B)<<" position in file: "<<ifs.tellg()<<"\r\n";
更新:我之前发布过你可以用 ifs >> R >> G >> B 替换 ifs.read();正如@Benjamin Lindley 指出的那样,这是不正确的,因为 >> 运算符用于格式化文本,而不是二进制。这意味着如果文件包含例如空格/换行符/等字符,操作员将跳过它并获取下一个字符。在这种简单的情况下,最好使用 ifs.get(char)。
【讨论】:
当然,除非@IInspectable 指出,该文件不像我以前测试的那样简单,在这种情况下,获取一个库并使用它来检查图像内部 我错过了很多次!很高兴它有帮助。你能把我的帖子标记为答案吗? 你绝对不能像那样读取 RGB 值。它们存储为二进制值,而不是文本。 布鲁斯,当然! :) 抱歉耽搁了,这个网站对我来说是新的【参考方案2】:您对需要检查的图像编码做了几个假设。
如果您查看BMP header,您会看到:
在偏移量 28 处,文件不一定像您假设的那样每个像素具有 3*8 位。每个像素可以有 1、4、8 或 24 位;
在偏移量 30 处,指定了压缩类型。可以为 0 无 (你的假设)但也是Running Length Encoding: 1=RLE-8 或 2=RLE-4。
在偏移量 34 处可以直接读取图像数据的大小(以字节为单位),无需自行计算。
还要注意sizeof(int)
理论上可能与4不同。这不是问题所在,但这解释了使用微软的DWORD
(用于int)和WORD
(简称)作为documented here的做法.
我怀疑您的文件中使用了 RLE:在这种情况下,由于压缩,您无法再查看固定位置的像素字节:您需要先解压缩数据。
【讨论】:
就我而言,就这么简单,这是我需要做的课堂作业:) 但感谢您的反馈,我真的很感激 :) 感谢您提供有关图像大小的信息! :)以上是关于从 bmp 文件中读取 RGB 像素的主要内容,如果未能解决你的问题,请参考以下文章