【问题标题】:How to read images using C如何使用 C 读取图像
【发布时间】:2021-12-03 10:41:45
【问题描述】:

有没有办法在 C 中使用 FILE fopen 读取图像像素或考虑图像的任何数据?我对图书馆不感兴趣。我尝试使用 fgetc 读取图像数据,但它会打印出一些没有任何意义的数字。

编辑:我知道它应该打印出数字,但我期待代表每个像素的数字。

编辑:我正在寻找可以帮助我理解 jpeg 或 png 格式如何工作和存储数据的文档链接。

【问题讨论】:

  • 是的,有办法。但是没有图书馆就很复杂。基本上,您需要重写用于解码 jpeg 和 png 图像的代码,这绝非易事。但是无论如何,当您使用fgetc 读取图像数据时,您期望得到什么输出。
  • 你期待什么?任何文件都只是一堆字节。如果将这些字节打印为数字,它们会以数字形式出现。要解释这些数字,您需要知道图像文件的确切格式。是时候阅读大量文档了...
  • 您对哪种图像格式感兴趣? PBM 很容易从 C 中解析出来。见en.wikipedia.org/wiki/Netpbm
  • 我有时间阅读文档,但我不知道在哪里可以找到它们。你们能给我一个链接,帮助我理解如何在没有库的情况下实现这一目标吗?
  • 我希望逐行显示二进制颜色

标签: c image png jpeg readimage


【解决方案1】:

如果您真的希望能够读取和写入图像,只需通过 FILE 指针,您将需要查看称为 .ppm 的文件格式。 (便携式像素图。)当然,这假设您可以将图像文件转换为 .ppm,但使用 imagemagick 命令行工具很容易实现。您可以使用 imagemagick 将您编写的 .ppms 转换为您喜欢的任何输出类型。

格式非常简单:

  • 以两个字符(“幻数”)“P6”开头
  • P6 后跟一个空格,然后是图像的宽度(以 ascii 表示)。
  • 宽度后跟一个空格,然后是图像的高度(以 ascii 表示)。
  • 标题的最后一位是条目的“最大值”。只需使用 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 无符号字符数组,在内存中随心所欲地操作它们,然后将这些数据写回另一个文件,就像我在此处的示例一样。

【讨论】:

    【解决方案2】:

    我不太明白你想做什么,但 C 语言是一种低级编程语言。当然,内存中只会有数字。

    在 C 中存储图像的最简单方法是创建矩阵结构并保留 RGB 值。你说的数字可以是每个像素的RGB值。

    【讨论】:

    • 它们不是,我使用的图像由一堆 79、79、79 组成,没有一个数字是 79。
    【解决方案3】:

    您可以不使用库来读取图像,但工作量很大。

    例如,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 的一个子集。

    【讨论】:

    • 是什么让 jpeg 图像如此难以阅读?
    • JPEG 是一种相当复杂的格式——图像存储为霍夫曼编码的 DCT 系数。更现代的格式再次变得更加困难:继任者 JPEG-XL 需要将近 200,000 行 C++ 才能读取。
    • 那么操作系统和浏览器都有读取jpeg文件的工具吧?
    • 没错,他们主要使用libjpeg-turbo,我在答案中链接的项目。读起来很有趣(如果有点复杂)。
    猜你喜欢
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    • 2012-01-11
    • 2011-01-16
    • 1970-01-01
    相关资源
    最近更新 更多