简体   繁体   English

从bmp文件读取RGB像素

[英]Reading RGB pixels from bmp file

I have a small bmp file and I want to get the RGB values of each pixel and output those values into a txt file if R, G, and B aren't all zero. 我有一个小的bmp文件,如果R,G和B都不都是零,我想获取每个像素的RGB值并将这些值输出到txt文件中。 I wrote the following program; 我编写了以下程序; it reads the header data correctly, but the RGB values aren't coming up. 它可以正确读取标头数据,但不会显示RGB值。 I assume I did something wrong in the for loop. 我假设我在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;


}

I ran the code and it works fine, I presume you mean by 'RGB values aren't coming up' you are not seeing the integer values, in which case this will fix it: 我运行了代码,它运行良好,我想您是说“ RGB值没有增加”,您看不到整数值,在这种情况下,可以解决此问题:

ofs<<"R: "<<int(R)<<" G: "<<int(G)<<" B: "<<int(B)<<"  position in file: "<<ifs.tellg()<<"\r\n";

Update: I posted earlier that you could replace ifs.read() with ifs >> R >> G >> B; 更新:我之前发布过,您可以将ifs.read()替换为ifs >> R >> G >> B; As @Benjamin Lindley points out, this is incorrect as the >> operator is for formatted text, not binary. 正如@Benjamin Lindley指出的那样,这是不正确的,因为>>运算符用于格式化的文本,而不是二进制的。 This means if the file contains eg a space/newline/etc character, the operator will skip it and take the next char. 这意味着如果文件包含例如空格/换行符/等字符,则操作员将跳过该文件并获取下一个字符。 Better to use ifs.get(char) in this simple case. 在这种简单情况下,最好使用ifs.get(char)。

You make several assumptions on the encoding of the image that you need to check. 您对需要检查的图像编码进行了几个假设。

If you look at the BMP header , you'll see: 如果查看BMP标头 ,则会看到:

  • at offset 28 that the file doesn't necessarily have 3*8 bits per pixel as you assume. 在偏移量28处,该文件不一定每个像素都具有3 * 8位。 It can have 1, 4, 8, or 24 bits per pixel; 每个像素可以具有1、4、8或24位;

  • at offset 30, the compression type is specified. 在偏移量30处,指定压缩类型。 It can be 0 for none (your assumption) but also be Running Length Encoding : 1=RLE-8 or 2=RLE-4. 它可以是0(无假设)(您的假设),也可以是运行长度编码 :1 = RLE-8或2 = RLE-4。

  • at offset 34 you can directly read the size of image data in bytes so that you don't need to calculate it on your own. 在偏移量34处,您可以直接读取以字节为单位的图像数据大小,因此您无需自己计算。

Attention also that sizeof(int) could be in theory different from 4. It's not the problem here, but this explains the practice of using microsoft's DWORD (for int) and WORD (for short) as documented here . 注意也是sizeof(int)可能是在理论上从4不同的这是不是这里的问题,但是这说明利用微软的做法DWORD (为int)和WORD (简称),作为记录在这里

I suspect that RLE is used in you file: In this case, due to the compression, you can no longer look at the pixel bytes at a fixed position: you'd need to uncompress the data first. 我怀疑您的文件中使用了RLE:在这种情况下,由于压缩,您不能再在固定位置查看像素字节:您需要首先解压缩数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM