用c读取PNG文件

Read PNG file with c

我想在没有任何库的情况下用 C 读取 PNG 图像文件。 PNG (Portable Network Graphics) Specification Version 1.0 任何 PNG 文件都有一个区别于其他图像格式的签名。签名是图片的前8个字节。

像上面的 RFC 这样的一些来源将签名提到为:

137 80 78 71 13 10 26 10 (decimal)

或像提到的签名为:

89 50 4E 47 0D 0A 1A 0A (ASCii)

所以,我写了一个简单的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE (8)

int main(int argc, char **argv){
    
    if(argc != 2) {
        printf("Usage: %s <png file>\n", argv[0]);
        return 1;
    }
    
    char *buf = (char *)malloc(MAX_SIZE);
    
    if(!buf) {
        fprintf(stderr, "Couldn't allocate memory\n");
        return 1;
    }
    
    FILE *f = fopen(argv[1], "r");
    
    if(!f) {
        perror("fopen");
        printf("Invalid file\n");
        
        free(buf);
        return 1;
    }
    
    int size = fread(buf, 1, MAX_SIZE, f);

    printf(%c\n", buf[1]);
    printf(%c\n", buf[2]);
    printf(%c\n", buf[3]);
    printf(%c\n", buf[4]);
    printf(%c\n", buf[5]);
    printf(%c\n", buf[6]);
    printf(%c\n", buf[7]);
    printf(%c\n", buf[8]);
      fclose(f);
      free(buf);
    system("pause");
    
    return 0;
}

当我按printf 打印字节时,输出与上面不同。 这是它显示的内容:

ëPNG→►v@,

谁能描述一下发生了什么,我可以做些什么来修改它?

您需要使用正确的格式说明符打印每个值。这里我们需要数字表示,而不是字符表示。

来自 printf 上的 documentation

  • %c 写入单个字符
  • %d 将有符号整数转换为十进制表示
  • %x 将无符号整数转换为十六进制表示

%02X 使用 ABCDEF (而不是 abcdef).

另见 implicit conversions

一个例子:

#include <stdio.h>

#define SIZE 8

int main(int argc, char **argv) {
    unsigned char magic[SIZE];
    FILE *file = fopen(argv[1], "rb");

    if (!file || fread(magic, 1, SIZE, file) != SIZE) {
        fprintf(stderr, "Failure to read file magic.\n");
        return 1;
    }

    /* Decimal */
    for (size_t i = 0; i < SIZE; i++)
        printf("%d ", magic[i]);
    printf("\n");

    /* Hexadecimal */
    for (size_t i = 0; i < SIZE; i++)
        printf("%02X ", magic[i]);
    printf("\n");

    fclose(file);
}

输出:

137 80 78 71 13 10 26 10 
89 50 4E 47 0D 0A 1A 0A