无法读取 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文件中图像的超链接以及页眉和页脚的内容?

MATLAB中图像的基本操作

tensorflow 中图像的读取

OpenCV中图像的读取,显示与保存

将反应项目部署到 github 页面面临公共文件夹中图像的问题

我无法删除 UITableViewCell 中图像的左边框