从位图中提取像素数据时出现问题
Problem extracting Pixel Data from bitmap
我使用本机 C++,没有从头开始构建图像处理库,目前用于位图。
例如,在将流的位置设置为正确位置后,我使用以下命令从位图中提取像素数据。
fread(pixelDataBuffer, sizeof(unsigned char), (height * width), streamIn);
其中 height 和 width 是位图图像的像素尺寸。我认为这对每像素 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 块,以便将来的可读性和可维护性。
我使用本机 C++,没有从头开始构建图像处理库,目前用于位图。
例如,在将流的位置设置为正确位置后,我使用以下命令从位图中提取像素数据。
fread(pixelDataBuffer, sizeof(unsigned char), (height * width), streamIn);
其中 height 和 width 是位图图像的像素尺寸。我认为这对每像素 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 块,以便将来的可读性和可维护性。