如何使用 C 读取图像
How to read images using C
有没有办法在 C 中使用 FILE fopen 读取图像像素或考虑图像的任何数据?我对图书馆不感兴趣。我尝试使用 fgetc 读取图像数据,但它打印出一些没有任何意义的数字。
编辑:我知道它应该打印出数字,但我期待的是代表每个像素的数字。
编辑:我正在寻找可以帮助我理解 jpeg 或 png 格式如何工作和存储数据的文档链接。
我不太明白你想做什么,但C语言是一种低级编程语言。当然,内存中只会有数字。
在 C 中存储图像的最简单方法是创建矩阵结构并保留 RGB 值。你说的数字可以是每个像素的RGB值。
如果您真的希望能够简单地通过 FILE 指针读取和写入图像,您将需要查看一种名为 .ppm 的文件格式。 (便携式像素图。)当然,这假定您可以将图像文件转换为 .ppm,但这可以使用 imagemagick command-line 工具轻松实现。您可以使用 imagemagick 将您写入的 .ppms 转换为您喜欢的任何输出类型。
格式非常简单:
- 以两个字符(“幻数”)“P6”开头
- P6 后跟一个空格,然后是图像的宽度(ascii 格式)。
- 宽度后跟一个空格,然后是图像的高度(以 ascii 格式表示)。
- header 的最后一位是条目的“最大值”。只需使用 255。在后面跟一个空格。
- 之后,您只需以二进制形式写入 RGB 值。每个通道一个无符号字符。
示例:
P6 128 128 255
[128 * 128 * 3 bytes of data go here, in row major order. The top-left
pixel is first, then the pixel to the right of it. When you get to the
end of a row, just write the first pixel of the next row. That's all
there is. No other header info, no terminators, etc.]
示例:
#include <stdio.h>
void main() {
FILE * out;
out = fopen("color_test.ppm", "wb");
fprintf(out, "P6 256 256 255\n");
for(int r=0; r<256; r++) {
for(int b=0; b<256; b++) {
fputc(r, out);
fputc(0, out);
fputc(b, out);
}
}
fclose(out);
}
这会生成:
读取文件同样简单。您可以将它们拉入一个 3d 无符号字符数组,随心所欲地在内存中操作它们,然后将该数据写回另一个文件,就像我在此处所做的示例一样。
您可以在不使用库的情况下读取图像,但是工作量很大。
例如,libjpeg-turbo 可能是最流行的读取 JPEG 图像的库:
https://github.com/libjpeg-turbo/libjpeg-turbo
大约有 50,000 行 C 语言和汇编代码。
有趣的是,它还包括读写一些其他格式的函数(这些例程被命令行JPEG工具用于文件格式转换)。例如,这里是 libjpeg-turbo 用来加载 BMP 图像的代码:
https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/rdbmp.c
大约 700 行,虽然它只能读取 BMP 的一个子集。
如果您正在寻找如何从像素中读取 RGB 值,请单击 this,如果您正在寻找库,那么 libjpeg 和 libpng 将帮助您。
有没有办法在 C 中使用 FILE fopen 读取图像像素或考虑图像的任何数据?我对图书馆不感兴趣。我尝试使用 fgetc 读取图像数据,但它打印出一些没有任何意义的数字。
编辑:我知道它应该打印出数字,但我期待的是代表每个像素的数字。
编辑:我正在寻找可以帮助我理解 jpeg 或 png 格式如何工作和存储数据的文档链接。
我不太明白你想做什么,但C语言是一种低级编程语言。当然,内存中只会有数字。
在 C 中存储图像的最简单方法是创建矩阵结构并保留 RGB 值。你说的数字可以是每个像素的RGB值。
如果您真的希望能够简单地通过 FILE 指针读取和写入图像,您将需要查看一种名为 .ppm 的文件格式。 (便携式像素图。)当然,这假定您可以将图像文件转换为 .ppm,但这可以使用 imagemagick command-line 工具轻松实现。您可以使用 imagemagick 将您写入的 .ppms 转换为您喜欢的任何输出类型。
格式非常简单:
- 以两个字符(“幻数”)“P6”开头
- P6 后跟一个空格,然后是图像的宽度(ascii 格式)。
- 宽度后跟一个空格,然后是图像的高度(以 ascii 格式表示)。
- header 的最后一位是条目的“最大值”。只需使用 255。在后面跟一个空格。
- 之后,您只需以二进制形式写入 RGB 值。每个通道一个无符号字符。
示例:
P6 128 128 255
[128 * 128 * 3 bytes of data go here, in row major order. The top-left
pixel is first, then the pixel to the right of it. When you get to the
end of a row, just write the first pixel of the next row. That's all
there is. No other header info, no terminators, etc.]
示例:
#include <stdio.h>
void main() {
FILE * out;
out = fopen("color_test.ppm", "wb");
fprintf(out, "P6 256 256 255\n");
for(int r=0; r<256; r++) {
for(int b=0; b<256; b++) {
fputc(r, out);
fputc(0, out);
fputc(b, out);
}
}
fclose(out);
}
这会生成:
读取文件同样简单。您可以将它们拉入一个 3d 无符号字符数组,随心所欲地在内存中操作它们,然后将该数据写回另一个文件,就像我在此处所做的示例一样。
您可以在不使用库的情况下读取图像,但是工作量很大。
例如,libjpeg-turbo 可能是最流行的读取 JPEG 图像的库:
https://github.com/libjpeg-turbo/libjpeg-turbo
大约有 50,000 行 C 语言和汇编代码。
有趣的是,它还包括读写一些其他格式的函数(这些例程被命令行JPEG工具用于文件格式转换)。例如,这里是 libjpeg-turbo 用来加载 BMP 图像的代码:
https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/rdbmp.c
大约 700 行,虽然它只能读取 BMP 的一个子集。
如果您正在寻找如何从像素中读取 RGB 值,请单击 this,如果您正在寻找库,那么 libjpeg 和 libpng 将帮助您。