【问题标题】:C/C++ Image Loading [closed]C/C++ 图像加载 [关闭]
【发布时间】:2011-03-18 02:29:08
【问题描述】:

我正在开发一个游戏引擎,而我对于为多种格式编写图像加载器太无能为力了,所以我的问题是:是否有一个抽象的图像加载库来加载图像文件?我只需要加载文件,然后使用像素数组将它们放到屏幕上。

【问题讨论】:

标签: c++ c image loading


【解决方案1】:

OpenImageIO 支持多种不同的文件格式,其中包括 TIFF、JPEG/JFIF、OpenEXR、PNG、HDR/RGBE、ICO、BMP、Targa、JPEG-2000、RMan Zfile、FITS、DDS、Softimage PIC、PNM、DPX 、Cineon、IFF、Field3D、Ptex、Photoshop PSD、Wavefront RLA、SGI、WebP 和 GIF

【讨论】:

    【解决方案2】:

    Boost's GIL 最初由 Adob​​e 开发。它可能不是最直观的,但它肯定是最完整和最强大的库之一。

    【讨论】:

    • boost::gil 本身不加载任何图像格式。它所做的是提供一个统一的接口来执行像素算法。 boost::gil 中的图像加载器助手要求您拥有相应的库(例如libtifflibpng 等)
    • CImg 也是如此,它本身支持几种格式,其余的需要第三方库。
    【解决方案3】:

    您可以查看SDL_Image,这是Simple DirectMedia Layer 的子项目。它作为加载几种不同图像格式的简单抽象。 SDL 是用 C 编写的,但很容易与 C 或 C++ 代码一起使用。

    【讨论】:

    • OP 甚至没有暗示 C 和 C++ 是“一种语言”。 OP 正在寻找 C 或 C++ 的解决方案。
    • @gbrandt,更新了我的答案以反映 SDL 的实现语言。
    【解决方案4】:

    另一种可能性(主要,如果不是专门用于 Windows)是CXImage。与许多其他产品相比,它的明显优势是支持多种相机原始格式,以防万一。

    【讨论】:

      【解决方案5】:

      我一直是CImg 的粉丝。它非常易于使用。另一位用户也喜欢the answer。我将发布我在答案中发布的相同示例,以便您了解访问像素和尺寸信息是多么容易。

      CImg<unsigned char> src("image.jpg");
      int width = src.width();
      int height = src.height();
      unsigned char* ptr = src.data(10,10); // get pointer to pixel @ 10,10
      unsigned char pixel = *ptr;
      

      【讨论】:

      • 可惜他们没有 64 位端口。至少他们在常见问题解答中是这样说的。
      • 什么意思?这个库只是一个头文件,它以 64 位模式编译。
      • 这也适用于 RGB 图像吗?大概不是因为你需要一个数组而不是 unsigned char?
      • 链接已断开
      【解决方案6】:

      如果您使用的是 OpenGL,那么 DevIL 是一个不错的选择,因为它的风格和约定比任何其他库都更符合 OpenGL。它的设置相对容易,并且对多种格式也有很好的支持。

      关于糟糕的事情的一件事。虽然设置经过良好测试并节省您时间的工作 3rd 方代码很好,但关于了解图像加载的工作原理以及为什么它以这种方式工作,还有一些话要说。如果你真的想擅长某件事,我相信你需要真正从头开始学习如何去做。即使您最终使用了第 3 方代码。

      【讨论】:

        【解决方案7】:

        FreeImage 是一个不错的开源库

        这是一个示例代码,数据可以通过“out.data()”访问

        FREE_IMAGE_FORMAT format = FreeImage_GetFileTypeU(filename.c_str());
        if (format == FIF_UNKNOWN)      format = FreeImage_GetFIFFromFilenameU(filename.c_str());
        if (format == FIF_UNKNOWN)      throw(std::runtime_error("File format not supported"));
        
        FIBITMAP* bitmap = FreeImage_LoadU(format, filename.c_str());
        FIBITMAP* bitmap2 = FreeImage_ConvertTo32Bits(bitmap);
        FreeImage_Unload(bitmap);
        
        std::vector<char> out(FreeImage_GetWidth(bitmap2) * FreeImage_GetHeight(bitmap2) * 4);
        FreeImage_ConvertToRawBits((BYTE*)out.data(), bitmap2, FreeImage_GetWidth(bitmap2) * 4, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true);
        
        FreeImage_Unload(bitmap2);
        

        【讨论】:

        • c++ 包装器似乎有点错误,至少在 g++ 中是这样。链接库是有问题的,尽管 c 版本工作正常。
        • 由于某种原因,库头尝试定义“WINDOWS”,这会干扰 Windows.h 头。 Windows.h 标头将其用作包含保护。不确定解决此问题的正确方法是什么。
        猜你喜欢
        • 1970-01-01
        • 2010-09-08
        • 1970-01-01
        • 2022-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-12
        • 1970-01-01
        相关资源
        最近更新 更多