【问题标题】:Writing a PNG in C++用 C++ 编写 PNG
【发布时间】:2014-04-30 02:55:49
【问题描述】:

我正在尝试在 Windows 7 64 位上使用 C++ 和 Visual Studio Express 2013 将一些数据写入 PNG 文件。我知道要做到这一点,我需要使用外部库,但这是我遇到一些困难的地方。

我尝试使用 LodePNG - 它看起来简单、轻巧且易于使用。问题是,它太简单了,而且似乎需要某种与我所拥有的不匹配的像素格式的数据。我可以修改我的数据以使其与 LodePNG 兼容,但我更愿意使用 libpng 等具有更多灵活性的库。

但是,我不明白关于构建或链接库的第一件事,而 libpng 已被证明是这方面的绝对噩梦。我尝试关注this guide,并设法生成“libpng.lib”和“png.h”,但是当我尝试将它们包含在我的项目中时(我将两个文件都放在我的项目目录中,添加了“png.h”到我的头文件并将“libpng.lib”添加到链接器的“附加依赖项”字段中),我得到了大量的构建错误,特别是:

error C1083: Cannot open include file: 'pnglibconf.h': No such file or directory

任何人都可以指导我如何安装 libpng,指导我找到有关该主题的良好指南(我对那里缺乏指南感到惊讶......),或推荐不同的(轻量级,易于安装)PNG库?我要疯了。

【问题讨论】:

  • 你真的真的不想直接使用 libpng。试试FreeImage,它很容易使用。你可能想看看ImageMagick,也许它已经有你想做的功能了。
  • 您可以从 libpng 源中的脚本目录中获取 pnglibconf.h。命名为 pnglibconf.h.prebuilt 那里。
  • 谢谢,我会看看 FreeImage、ImageMagick 和 GDI+。 @Ivarpoiss我相信我试过了,它抱怨另一个文件(可能是pngconf.h)
  • Ivarpoiss:感谢您指出这一点!这是我的正确答案!

标签: c++ png libpng


【解决方案1】:

丢失的头文件可能是因为您还需要指定其他包含目录以指向 libpng 的头文件。看起来您可能链接正确。

我已经有一段时间没有在视觉工作室做这个了,但是在项目配置中应该有一个字段。

【讨论】:

    【解决方案2】:

    考虑以here 指定的 NetPBM/PBMplus 格式编写文件。这非常简单,您不需要库,因为文件非常简单。维基百科文章显示格式here

    这是一个简单的例子:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(){
    
       FILE *imageFile;
       int x,y,pixel,height=100,width=256;
    
       imageFile=fopen("image.pgm","wb");
       if(imageFile==NULL){
          perror("ERROR: Cannot open output file");
          exit(EXIT_FAILURE);
       }
    
       fprintf(imageFile,"P5\n");           // P5 filetype
       fprintf(imageFile,"%d %d\n",width,height);   // dimensions
       fprintf(imageFile,"255\n");          // Max pixel
    
       /* Now write a greyscale ramp */
       for(x=0;x<height;x++){
          for(y=0;y<width;y++){
             pixel=y;
             fputc(pixel,imageFile);
          }
       }
    
       fclose(imageFile);
    }
    

    将文件设为 PBM/PGM frmat 后,使用 ImageMagick (here) 使用以下简单命令将其转换为 PNG:

    convert file.pgm file.png
    

    【讨论】:

      【解决方案3】:

      LodePNG 就像你说的那样简单。我以前也用过。以防万一您改变主意并决定将您拥有的数据编码为正确的格式(假设它是BGRA)。以下将按照lodepng的要求将BGRA格式转换为RGBA ..

      std::vector<std::uint8_t> PngBuffer(ImageData.size());
      
      for(std::int32_t I = 0; I < Height; ++I)
      {
          for(std::int32_t J = 0; J < Width; ++J)
          {
              std::size_t OldPos = (Height - I - 1) * (Width * 4) + 4 * J;
              std::size_t NewPos = I * (Width * 4) + 4 * J;
              PngBuffer[NewPos + 0] = ImageData[OldPos + 2]; //B is offset 2
              PngBuffer[NewPos + 1] = ImageData[OldPos + 1]; //G is offset 1
              PngBuffer[NewPos + 2] = ImageData[OldPos + 0]; //R is offset 0
              PngBuffer[NewPos + 3] = ImageData[OldPos + 3]; //A is offset 3
          }
      }
      
      std::vector<std::uint8_t> ImageBuffer;
      lodepng::encode(ImageBuffer, PngBuffer, Width, Height);
      lodepng::save_file(ImageBuffer, "SomeImage.png");
      

      【讨论】:

      • 奇怪的是 lodepng 文档没有提到这一点。它给人的印象是它可以加载任何支持 png 的格式。
      • lodepng 非常适合我的简单用例。
      猜你喜欢
      • 2018-01-19
      • 1970-01-01
      • 2012-05-30
      • 2013-08-03
      • 2020-08-04
      • 1970-01-01
      • 2021-04-11
      • 1970-01-01
      • 2013-05-19
      相关资源
      最近更新 更多