【发布时间】:2014-12-25 05:46:34
【问题描述】:
我想从 BMP 文件中读取所有像素的 RGB 值。 我有 C++ 代码,看起来像:
#include <iostream>
#include <fstream>
using namespace std;
int main () {
FILE *streamIn;
streamIn = fopen("./Untitled.bmp", "r");
if (streamIn == (FILE *)0) {
printf("File opening error ocurred. Exiting program.\n");
return 0;
}
unsigned char info[54];
fread(info, sizeof(unsigned char), 54, streamIn);
int width = *(int*)&info[18];
int height = *(int*)&info[22];
int image[width*height][3];
int i = 0;
for(i=0;i<width*height;i++) {
image[i][2] = getc(streamIn);
image[i][1] = getc(streamIn);
image[i][0] = getc(streamIn);
printf("pixel %d : [%d,%d,%d]\n",i+1,image[i][0],image[i][1],image[i][2]);
}
fclose(streamIn);
return 0;
}
和这样的图像(网格叠加):
这是 6x12 像素的文件,有两种颜色 - 黑色和白色。
我试图找出为什么在以图像作为参数执行上述代码后,我不仅得到 RGB 像素:[0,0,0] 和 [255,255,255],而且还得到 [0,248,0],[ 7,224,0] 等。
该文件的十六进制转储是:
0000-0010: 42 4d 9a 01-00 00 00 00-00 00 7a 00-00 00 6c 00 BM...... ..z...l.
0000-0020: 00 00 08 00-00 00 0c 00-00 00 01 00-18 00 00 00 ........ ........
0000-0030: 00 00 20 01-00 00 13 0b-00 00 13 0b-00 00 00 00 ........ ........
0000-0040: 00 00 00 00-00 00 42 47-52 73 00 00-00 00 00 00 ......BG Rs......
0000-0050: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 ........ ........
0000-0060: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 ........ ........
0000-0070: 00 00 00 00-00 00 00 00-00 00 02 00-00 00 00 00 ........ ........
0000-0080: 00 00 00 00-00 00 00 00-00 00 ff ff-ff ff ff ff ........ ........
0000-0090: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-00a0: ff ff ff ff-ff 00 00 00-00 00 00 00-00 00 00 00 ........ ........
0000-00b0: 00 00 00 00-00 00 00 ff-ff ff ff ff-ff 00 00 00 ........ ........
0000-00c0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 ff ........ ........
0000-00d0: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-00e0: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-00f0: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-0100: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-0110: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-0120: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-0130: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-0140: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-0150: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-0160: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-0170: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-0180: ff ff ff ff-ff ff ff ff-ff ff ff ff-ff ff ff ff ........ ........
0000-0190: ff ff 00 00-00 ff ff ff-00 00 00 ff-ff ff 00 00 ........ ........
0000-019a: 00 ff ff ff-00 00 00 ff-ff ff ........ ..
文件大小为 410 字节。它应该是 270 (6*12*3 + 54)。这意味着这个文件中有一些额外的信息。
【问题讨论】:
-
6 像素宽的 BMP 图像在每行像素后都有填充。 (一行像素必须包含可被 4 整除的字节数,因此 6x3 在每 6 个像素之后有两个填充像素。您还应该查看适当的标题信息以确保您的 BMP 是 24 位 RGB位图。
-
位图文件格式并不容易(它取决于图像格式如何写入磁盘)。那就是为什么 1) 为什么不使用 WinSDK 结构来处理 BMP? 2)它非常不便携(读取字节数组并访问未对齐的整数......)
-
为了简洁起见:
using namespace是 C++,其余代码和标签为C。是哪个? -
@trojek:填充是存储为 24 位颜色的 BMP 文件的问题;在您的情况下,这可能不是问题。我真的怀疑你有单色位图或其他东西。检查标题中的颜色深度。
-
您确定从正确的索引读取像素缓冲区吗?一些应用程序在 DIB (40) 标头之后添加数据位,因此,使实际像素从偏移量 52、54、56、102 或 140 等开始...编辑:并且 - 虽然有点“意外” - 那么位图压缩? (RLE、DXT...)