无法读取 C 中图像的所有字节 [重复]
Posted
技术标签:
【中文标题】无法读取 C 中图像的所有字节 [重复]【英文标题】:Not able to read all bytes of image in C [duplicate] 【发布时间】:2021-01-30 11:09:28 【问题描述】:我想编写一个 C 程序来读取 png 的像素值,而无需任何外部库(不包括用于解压缩的 zlib)。我研究了 png 的 Wikipedia page 并看到了一些 python tutorials 做同样的事情。
目前,我正在尝试将 png 的字节读入一个数组。目前,我正在使用this picture,它有一些黑点,我将使用这些黑点来验证最终数组中的像素坐标。但是,在打印检索到的数组时,我只得到了 png 的前四个字节:
ëPNG
当我询问数组的 sizeof() 并返回 4 时,我验证它实际上不是打印字节问题。我不明白这段代码有什么问题:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
FILE *fp = fopen(argv[1], "rb");
unsigned char* file_data;
fseek(fp, 0, SEEK_END);
long int length = ftell(fp);
rewind(fp);
file_data = (char *)malloc((length+1)*sizeof(char));
fread(file_data, length, 1, fp);
printf("%s\n", file_data);
printf("%d\n", sizeof(file_data)/sizeof(file_data[0]));
fclose(fp);
return 0;
【问题讨论】:
sizeof
指针与真实数组上的 sizeof
不同。前者只给出指针大小,而不给出它指向的内存缓冲区的大小。
即使在达到这一点之后,是什么让您认为 PNG 的原始文件格式可以作为终止的 C 字符串打印?
忽略fread()
的返回值,后果自负。如果您切换参数以使其为fread(file_data, 1, length, fp);
,它会准确告诉您读取了多少(多少元素)
【参考方案1】:
WhozCraig 是对的。所有字节都在那里,但您试图将其视为一个字符串,在 C 中它以空字节 ('\0'
) 终止。在我的系统和 LLDB 上的 PNG 上运行此代码显示 file_data
实际上正在加载超过四个字节:
(lldb) expr file_data
(unsigned char *) $0 = 0x0000000100205e40 "\x89PNG\r\n\x1a\n"
但是下一个字节是在十六进制编辑器中显示的空字节(所选字节是打印的):
所以“字符串”停在那里。
将第 14 行更改为以下内容:
for (int i = 0; i < length; i++)
printf("%x", file_data[i]);
printf("%s\n", "");
显示所有字节:
89504e47da1aa000d494... [truncated]
您应该知道的其他一点是,sizeof
不适用于在编译时大小未知的数组(VLA 有少数例外,此处均不适用)。
printf("%d\n", sizeof(file_data)/sizeof(file_data[0]));
在这一行中,sizeof(file_data)
最终查询了file_data
类型的大小,即unsigned char *
。在我和任何 64 位系统上,这将解析为 8
(您可能在 32 位系统上,在这种情况下它会解析为 4
)。 sizeof(file_data[0])
查询数组第一个元素的大小,它的类型为unsigned char
。 (unsigned
) char
被定义为在 sizeof
调用中始终计算为 1
,因此整个表达式解析为:
printf("%d\n", 8 / 1);
// 4 on your system
这就是为什么您尝试查找数组的大小会打印出4
。
【讨论】:
对错误问题的一个很好的回答 :-) 在开头添加一点解释为什么printf("%d\n", sizeof(file_data)/sizeof(file_data[0]));
是错误的,值得一票
@John3136 完成!我真的不确定为什么人们投票反对。我的理解是他们认为他们的程序只获取前 4 个字节,所以我主要是想澄清这一点。以上是关于无法读取 C 中图像的所有字节 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用php读取docx文件中图像的超链接以及页眉和页脚的内容?