用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).
一个例子:
#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
我想在没有任何库的情况下用 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).
一个例子:
#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