从位图读取RGB - 错误的值(RGB); C++

tro*_*jek 2 c++ rgb image bitmap

我想从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;
}
Run Code Online (Sandbox Code Playgroud)

和这样的图像(网格重叠):

6x12像素位图文件,白色和黑色 -  24位格式

这是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                    ........ ..
Run Code Online (Sandbox Code Playgroud)

文件大小为410字节.它应该是270(6*12*3 + 54).这意味着此文件中有一些额外的信息.

γηρ*_*όμε 5

您的位图文件包括:

位图文件头:14个字节
42 4d 9a 01-00 00 00 00-00 00 7a 00-00 00

最后4个字节是rgb值开始的偏移量,7A = after 122 Bytes

DIB头first 4 bytes是大小:
6c 00 00 00 -> 108 Bytes so BITMAPV4HEADER

接下来的8个字节是宽度和高度(以像素为单位):
08 00-00 00 0c 00-00 00 width height each 4 Bytes

所以你的位图是没有 6x12,但8x12!不需要填充,因为8x3 = 24是4的倍数.

实际像素是从0x7A - 0x199 最后一行开始向上,从左到右,位图是:

在此输入图像描述

文件大小正确:

file size = Bitmap File Header + DIB header + rgb Bytes = 14 + 108 + 8 * 12 * 3 = 410

要读取图片中的特定像素:

加载整个位图文件

char *buff;
char rgb[8 * 12 * 3]; //for simplicity
fptr = fopen("....bmp", "rb");

fseek(fptr, 0, SEEK_END);
int file_Size = ftell(fptr);
fseek(fptr, 0, SEEK_SET);

buff = malloc(file_Size * sizeof(char));

fread(buff, sizeof(char), file_Size, fptr);

memmove(rgb, buff[0x7A], 8 * 12 * 3);
Run Code Online (Sandbox Code Playgroud)

现在rgb包含实际像素,但顺序为left-> right和down-> up表示第一个像素是图像左下角的像素.