Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
152 views
in Technique[技术] by (71.8m points)

c++ - How do I install and use PNGwriter to write PNG image files?

I'd like to learn how to write PNG images pixel-by-pixel using both RGB and HSV color models with C++. I read that this should be fairly easy using PNGwriter (https://github.com/pngwriter/pngwriter), but I've spent many hours struggling with installing it (on Ubuntu) and compiling my code with it. Any help would be much appreciated.

Disclaimer: I have a weird background in the sense that I have many years of experience in using Unix-like operating systems, doing stuff in the terminal, and writing code, but I know little/nothing about installing software from the source code or compiling programs manually or with makefiles from multiple source code files.

The installation instructions on GitHub advise to do one of the following:

Spack:

   spack install pngwriter
   spack load pngwriter

From Source:

First install the dependencies zlib, libpng, and (optional for text support) freetype. PNGwriter >can then be installed using CMake:

   git clone https://github.com/pngwriter/pngwriter.git
   
   mkdir -p pngwriter-build
   cd pngwriter-build
   
   # for own install prefix append: -DCMAKE_INSTALL_PREFIX=$HOME/somepath
   cmake ../pngwriter
   
   make -j
   
   # optional
   make test
   
   # sudo is only required for system paths
   sudo make install

I managed to install Spack and then PNGwriter, but couldn't compile the simplest program with it and wasn't able to figure out why. I then installed PNGwriter manually, but still couldn't compile anything with it. This was many hours of struggling ago so I, unfortunately, don't remember what kind of errors or problems I was encountering at this point.

The instructions on GitHub say the following about linking:

First set the following environment hint if PNGwriter was not installed in a system path:

   # optional: only needed if installed outside of system paths
   export CMAKE_PREFIX_PATH=$HOME/somepath:$CMAKE_PREFIX_PATH

Use the following lines in your projects CMakeLists.txt:

   find_package(PNGwriter 0.7.0)
   
   if(PNGwriter_FOUND)
     target_link_libraries(YourTarget PRIVATE PNGwriter::PNGwriter)
   endif(PNGwriter_FOUND)

Questions: How do I know if PNGwriter was or wasn't installed in a system path? I have libPNGwriter.a in /usr/local/lib and pngwriter.h in /usr/local/include --- does this mean that it was installed in a system path? When installing I simply tried to follow the instructions above. Do I just type the environment hint to the terminal or add it to some file? If the former then does it need to be given every time I open a new terminal session? Is "somepath" /usr/local/lib, /usr/local/include or something else?

Questions: Does the second part regarding "CMakeLists.txt" depend on whether PNGwriter was installed in a system path? What is "CMakeLists.txt"? I assume it's some file one's IDE creates, but my NetBeans projects don't seem to contain such files. What if I have a single source file and compile it manually in the terminal?

Now, let's say I'd like to compile the PNGwriter quickstart example:

   #include <pngwriter.h>
   
   int main()
   {
     int i;
     int y;
     pngwriter png(300, 300, 0, "test.png");
     for(i = 1; i ≤ 300; i++)
     {
       y = 150 + 100*sin((double)i*9/300.0);
       png.plot(i, y, 0.0, 0.0, 1.0);
     }
     png.close();
     return 0;
   }

The PNGwriter manual instructs to compile as

    g++ myprogram.cc -o my_program `freetype-config --cflags` -I/usr/local/include -L/usr/local/lib -lpng -lpngwriter -lz -lfreetype

but I get errors

    $ g++ example.cpp -o example `freetype-config --cflags` -I/usr/local/include  -L/usr/local/lib -lpng -lpngwriter -lz -lfreetype
    Package freetype2 was not found in the pkg-config search path.
    Perhaps you should add the directory containing `freetype2.pc'
to the PKG_CONFIG_PATH environment variable
    Package 'freetype2', required by 'virtual:world', not found
    Package freetype2 was not found in the pkg-config search path.
    Perhaps you should add the directory containing `freetype2.pc'
to the PKG_CONFIG_PATH environment variable
    Package 'freetype2', required by 'virtual:world', not found
    Package freetype2 was not found in the pkg-config search path.
    Perhaps you should add the directory containing `freetype2.pc'
to the PKG_CONFIG_PATH environment variable
    Package 'freetype2', required by 'virtual:world', not found
    Package freetype2 was not found in the pkg-config search path.
    Perhaps you should add the directory containing `freetype2.pc'
to the PKG_CONFIG_PATH environment variable
    Package 'freetype2', required by 'virtual:world', not found
    sed: -e expression #1, char 0: no previous regular expression
    sed: -e expression #1, char 0: no previous regular expression
    In file included from example.cpp:1:0:
    /usr/local/include/pngwriter.h:66:22: fatal error: ft2build.h: No such file or directory
    compilation terminated.

The answer to this Stack Overflow question (Trying to install pygame on ubuntu which gives error) suggests to install libfreetype6-dev, but I apparently have the latest version already whereby the errors remain unchanged. If I instead actually add the directory containing freetype2.pc (I found it by going to / and using find -name "freetype2.pc") to the environment variable (added export PKG_CONFIG_PATH="/usr/lib/x86_64-linux-gnu/pkgconfig/:$PKG_CONFIG_PATH to ~/.bashrc and did source ~/.bashrc) then I get new errors

    $ g++ example.cpp -o example `freetype-config --cflags` -I/usr/local/include  -L/usr/local/lib -lpng -lpngwriter -lz -lfreetype
    /usr/bin/ld: cannot find -lpngwriter
    collect2: error: ld returned 1 exit status

Here I figured out that I needed to replace -lpngwriter with -lPNGwriter (i.e., the manual is erroneous). Then I get:

    $ g++ example.cpp -o example `freetype-config --cflags` -I/usr/local/include  -L/usr/local/lib -lpng -lPNGwriter -lz -lfreetype
    /usr/bin/ld: /usr/local/lib/libPNGwriter.a(pngwriter.cc.o): undefined reference to symbol 'png_set_sig_bytes@@PNG12_0'
    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libpng.so: error adding     symbols: DSO missing from command line
    collect2: error: ld returned 1 exit status

This is where I'm currently stuck. I can't seem to find a solution by googling (at least one that I'd understand).

Question: How do I get this working? How do I get it working in NetBeans? Do I get these problems because I effed up the linking step above?

Edit1: As per john's comment, I tried swapping -lpng and -lPNGwriter and I again get new errors:

    $ g++ example.cpp -o example `freetype-config --cflags` -I/usr/local/include  -L/usr/local/lib -lPNGwriter -lpng -lz -lfreetype
    /usr/local/lib/libPNGwriter.a(pngwriter.cc.o): In function `pngwriter::close()':
    pngwriter.cc:(.text+0x41c2): undefined reference to `png_convert_to_rfc1123_buffer'
    /usr/local/lib/libPNGwriter.a(pngwriter.cc.o): In function `pngwriter::read_png_info(_IO_FILE*, png_struct_def**, png_info_def**)':
    pngwriter.cc:(.text+0x4fdf): undefined reference to `png_set_longjmp_fn'
    collect2: error: ld returned 1 exit status

I'm still left clueless.

question from:https://stackoverflow.com/questions/65643751/how-do-i-install-and-use-pngwriter-to-write-png-image-files

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Thanks to john, I think I got it figured out. My guess is that the installation from the source (after the Spack installation) messed things up somehow. I reinstalled PNGwriter using Spack and, now apparently having all the pieces for the compilation command, was finally able to compile the example code.

Summary:

Source Spack

    # For bash/zsh/sh
    $ . spack/share/spack/setup-env.sh
    
    # For tcsh/csh
    $ source spack/share/spack/setup-env.csh
    
    # For fish
    $ . spack/share/spack/setup-env.fish

Install using Spack (skip if already installed)

    spack install pngwriter

Load PNGwriter (I guess one needs to do this in every new terminal session)

    spack load pngwriter

Compile (note that this isn't quite what the PNGwriter manual suggests)

    g++ example.cpp -o example `freetype-config --cflags` -I/usr/local/include  -L/usr/local/lib -lPNGwriter -lpng -lz -lfreetype

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...