【问题标题】:Reading an image file in C/C++ [closed]在 C/C++ 中读取图像文件 [关闭]
【发布时间】:2011-01-05 19:07:10
【问题描述】:

我需要读取 C/C++ 中的图像文件。如果有人可以为我发布代码,那就太好了。

我处理灰度图像,图像是 JPEG。我想将图像读入二维数组,这将使我的工作变得容易。

【问题讨论】:

  • libjpeg (ijg.org) 的文档或您没有的任何本机 API 是否不足?
  • 别忘了为您提出的三个问题选择一个正确答案。

标签: c++ c jpeg


【解决方案1】:

如果您决定采用最小的方法,不依赖 libpng/libjpeg,我建议使用 stb_imagestb_image_write,找到 here

这很简单,您只需将头文件stb_image.hstb_image_write.h 放在您的文件夹中。

这是您读取图像所需的代码:

#include <stdint.h>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

int main() {
    int width, height, bpp;

    uint8_t* rgb_image = stbi_load("image.png", &width, &height, &bpp, 3);

    stbi_image_free(rgb_image);

    return 0;
}

这是编写图像的代码:

#include <stdint.h>

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

#define CHANNEL_NUM 3

int main() {
    int width = 800; 
    int height = 800;

    uint8_t* rgb_image;
    rgb_image = malloc(width*height*CHANNEL_NUM);

    // Write your code to populate rgb_image here

    stbi_write_png("image.png", width, height, CHANNEL_NUM, rgb_image, width*CHANNEL_NUM);

    return 0;
}

您可以在没有标志或依赖项的情况下进行编译:

g++ main.cpp

其他轻量级替代方案包括:

【讨论】:

  • 我必须包含 math.h 库并在编译时链接它 (stackoverflow.com/questions/8671366/…) 否则我会在图像库中获得未定义的 pow 引用。
  • 我知道这只是一个例子,但你能澄清一下代码中神奇数字 3 的含义吗?
  • @mattshu 这是通道数(红色、绿色、蓝色),也许我应该在我的代码中澄清这一点,我会进行编辑。
  • 如果没有任何奇怪的库,我将如何做这样的事情?我不是这个问题的作者,但我想知道如何仅使用标准库(如 stdio.h)来做到这一点实际上,如何仅使用 stdio.h 来做到这一点?
  • 机顶盒开发人员不好。
【解决方案2】:

查看此线程:read and write image file

另外,看看this other question at Stackoverflow

【讨论】:

    【解决方案3】:

    查看 英特尔 Open CV 库 ...

    【讨论】:

      【解决方案4】:

      corona 很好。来自教程:

      corona::Image* image = corona::OpenImage("img.jpg", corona::PF_R8G8B8A8);
      if (!image) {
        // error!
      }
      
      int width  = image->getWidth();
      int height = image->getHeight();
      void* pixels = image->getPixels();
      
      // we're guaranteed that the first eight bits of every pixel is red,
      // the next eight bits is green, and so on...
      typedef unsigned char byte;
      byte* p = (byte*)pixels;
      for (int i = 0; i < width * height; ++i) {
        byte red   = *p++;
        byte green = *p++;
        byte blue  = *p++;
        byte alpha = *p++;
      }
      

      pixels 将是一维数组,但您可以轻松地将给定的 x 和 y 位置转换为一维数组中的位置。像 pos = (y * width) + x

      【讨论】:

        【解决方案5】:

        【讨论】:

          【解决方案6】:

          您可以通过查看 JPEG format 来编写自己的代码。

          也就是说,尝试使用预先存在的库,例如 CImgBoost's GIL。或者对于严格的 JPEG,libjpeg。 CodeProject 上还有CxImage 类。

          这是big list

          【讨论】:

          • Boost.GIL 不起作用,也没有得到维护。
          • 由于允许使用 C,我将 libjpeg 列为最轻量级的解决方案。 CImg 和 GIL 在语法上绝对更容易——但也需要 libjpeg。您可以轻松地将数据从 CImg 对象复制到某个 STL 容器或数组中。
          • CImg 也使用类似 LGPL 的许可证,该许可证比 libjpeg 的类似 BSD 的许可证限制得多。
          【解决方案7】:

          试用CImg 库。 tutorial 将帮助您熟悉。一旦你有了一个 CImg 对象,data() 函数就会让你访问二维像素缓冲区数组。

          【讨论】:

          • 实际上它被建模为一个 4D 像素矩阵,虽然 2D 灰度图像的深度和颜色维度设置为 1。在引擎盖下它是模板类型 T 的一维数组。
          • 我相信 CImg 需要 libjpeg 来加载 jpeg。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-03-12
          • 2017-05-04
          • 1970-01-01
          • 2016-08-22
          • 1970-01-01
          • 2016-08-08
          • 1970-01-01
          相关资源
          最近更新 更多