【发布时间】:2012-07-27 20:42:00
【问题描述】:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int main()
{
FILE* bmp = NULL;
uint32_t offset;
uint8_t* temp = NULL;
size_t read;
unsigned int x_dim = 600, y_dim = 388;
bmp = fopen("test_colour.bmp", "r");
if (!bmp)
return -1;
/* Get the image data offset */
fseek(bmp, 10, SEEK_SET);
fgets((char*)&offset, 4, bmp);
printf("Offset = %u\n", offset);
temp = malloc(3*x_dim*y_dim*sizeof(uint8_t));
if (!temp)
return -1;
/* Go the the position where the image data is stored */
fseek(bmp, offset, SEEK_SET);
/* Copy image data to array */
printf("%u bytes requested!\n", 3*x_dim*y_dim);
read = fread((void*)temp, sizeof(uint8_t), 3*x_dim*y_dim, bmp);
printf("%Iu bytes read!\n", read);
fclose(bmp);
free(temp);
return 0;
}
我正在使用上述代码将每像素 24 位 BMP 图像的 RGB 数据读取到数组中。根据 BMP 规范,从图像数据开始(在 BMP 标头之后)的文件开头的偏移量在偏移量 10 处给出。执行上述代码时,我得到以下输出。
Offset = 54
698400 bytes requested!
33018 bytes read!
偏移量输出似乎是正确的,因为文件大小为 698454 字节 (=698400+54)。但是,fread() 返回的值似乎表明无法读取整个图像数据。但是,我随后使用 temp 数组中的数据将 RGB 数据转换为灰度,然后再次将这些数据写入 BMP 文件。目视检查输出图像并不表示有任何错误,即似乎我实际上首先读取了整个输入图像,尽管fread() 似乎表示不同。
有人可以解释这种行为吗?
【问题讨论】:
-
两个问题:1)你能在调用
fread之后检查temp的内容,看看它是否真的在33018字节后停止读取? 2) 我不熟悉%Iu格式说明符 - 你能在调试器中检查read的实际值吗? -
我不认为这是导致您看到的症状的原因,但您应该使用正确的
printf格式字符串。size_t的格式是"%zu"。"%Iu"是非标准的。如果你的实现不支持"%zu",你可以使用printf("%lu bytes read!\n", (unsigned long)read); -
我正在使用 gcc 和 MinGW 进行编译,编译器无法识别
%zu说明符(我之前尝试过使用该说明符)。我读到必须在 Windows 中使用%Iu。 -
@simon:请参阅stackoverflow.com/a/10680635/12711,了解为什么 MinGW 在支持的
printf()格式说明符上可能会有些混乱。较新的 MinGW 版本和/或较新版本的 MSVCRT.DLL 似乎支持越来越多的 C99 标准说明符。 -
“但是,我随后使用临时数组中的数据将 RGB 数据转换为灰度数据,并将此数据再次写入 BMP 文件”。你能测试一下新bmp文件的大小吗?它大于 33 KB 吗? nem文件的尺寸是600*388像素吗?