从位图中提取像素数据时出现问题

Problem extracting Pixel Data from bitmap

我使用本机 C++,没有从头开始构建图像处理库,目前用于位图。

例如,在将流的位置设置为正确位置后,我使用以下命令从位图中提取像素数据。

fread(pixelDataBuffer, sizeof(unsigned char), (height * width), streamIn);

其中 heightwidth 是位图图像的像素尺寸。我认为这对每像素 8 位的图像有效并且有意义,但它仍然无效(函数 returns 0)。即使高度和宽度的值各为 256,并且 pixelDataBuffer 初始化如下:

unsigned char pixelDataBuffer[height * width]; 
// also tried:
unsigned char pixelDataBuffer[65536]; // which is 256*256

谢谢!

为清楚起见添加更多代码:

bool isTrial = true;
FILE *streamIn;
FILE *outputFile;

int main(int argc, const char * argv[]) {

    if (isTrial) {
        streamIn = fopen("Images/cameraman.bmp", "rb");
        outputFile = fopen("Images/cameraman_copy.bmp", "wb");
    } else {
        streamIn = fopen("Images/flag.bmp", "rb");
        outputFile = fopen("Images/flag_copy.bmp", "wb");
    }

    unsigned char header[54];
    unsigned char colourTable[1024];

    if (streamIn == nullptr) {
        printf("null pointer");
    } else {

        for (int i = 0; i < 54; i++) {
            header[i] = getc(streamIn);
        }

        unsigned int width = *(int*)&header[18];
        cout << "width: " << width << "\n"; // = 256

        unsigned int height = *(int *)&header[22];
        cout << "height: " << height << "\n"; // = 256

        unsigned short bitDepth = *(short *)&header[28];
        cout << "bitDepth: " << bitDepth << "\n"; // = 8

        unsigned int fileSize = *(int *)&header[2];
        cout << "fileSize: " << fileSize << endl; // 66614

        if (1 < bitDepth && bitDepth <= 8) {
            short count = fread(colourTable, sizeof(unsigned char), 1024, streamIn); 
            if (count == 1024) {
                printf("colourTable read\n"); // colourTable gets read
            } else {
                printf("colourTable NOT read properly");
            }
        } else {
            printf("bitsPerPixel / bitDepth is more than 8");
        }


        { // getting pixelData, at this point I assumed that the stream's position starts where pixel data starts (i.e. after Headers & ColourTable)

            unsigned int pixelDataSize = height * width * (bitDepth/8); // = 65536
            cout << "pixelDataSize: " << pixelDataSize << endl;

            unsigned char pixelDataBuffer[pixelDataSize]; // also tried initializing like unsigned char pixelDataBuffer[height*width]

            short counter = fread(pixelDataBuffer, sizeof(unsigned char), pixelDataSize, streamIn);
            cout << "counter: " << counter << endl; // = 0 THIS IS THE ISSUE. Documentation says "If either size or count is zero, the function returns zero and both the stream state and the content pointed by ptr remain unchanged." But I think I have size and count >0 correctly?

        }


        { // writing our header onto the outputFile
            short count = fwrite(header, sizeof(unsigned char), 54, outputFile);
            if (count == 54) {
                printf("header written\n"); // Header gets written
            } else {
                printf("header not written");
            }
        }
    }
    return 0;
}

您的问题是将 fread 的结果声明为 short。

尽量始终使用自动。使用:

auto counter = fread(pixelDataBuffer, sizeof(unsigned char), pixelDataSize, streamIn);

让它发挥作用。问题是 65536 不能简而言之,实际上它溢出了它,以至于看起来结果是 0。

如果您使用的是旧版本的 C++(C++11 之前)并且您不能使用 auto,请改用 size_t(这是实际的 return 类型的 fread)。

我还建议您学习将代码分解成更小的函数,避免编写巨大的 if 块,以便将来的可读性和可维护性。