The way CImg programs need to be built is sadly not abundantly clear from the documentation. Here is my take on it:
Step 1 - Do you need to display images on the screen?
No, don't laugh, you may be manipulating images on a headless web server.
- If you do NOT need to display images, you must do
#define cimg_display 0
before you include "CImg.h"
- If you do need to display images, and you are on Windows, you need to link with
gdi32
- If you do need to display images and you are on macOS, OSX, or Unix/Linux, you need to set the header include path for, and link with, X11
Step 2 - Do you need to read/write PNG format images?
If you do NOT need this functionality, or if you are happy to let CImg use your already-installed ImageMagick to read/write PNG images, do nothing.
If you want to use CImg's built-in ability to read/write PNG images, you need to #define cimg_use_png 1
before you include "CImg.h"
, and you need to set the header include path for libpng and link with both libpng
and libz
.
Step 3 - Do you need to read/write JPEG format images?
If you do NOT need this functionality, or if you are happy to let CImg use your already-installed ImageMagick to read/write JPEG images, do nothing.
If you want to use CImg's built-in ability to read/write JPEG images, you need to #define cimg_use_jpeg 1
before you include "CImg.h"
, and you need to set the header include path for libjpeg and link with libjpeg
.
Step 4 - Other stuff
One further thing is that you may need to link with the maths and the POSIX threads library (using -lm -lpthread
as linker switches), but I am not sure how to check that across all platforms, so I'll leave that to you - it can probably do no harm to add it.
So, bearing all that in mind, and using this little test program:
#include "CImg.h"
using namespace cimg_library;
int main() {
CImg<unsigned char> img(640,400,1,3); // Define a 640x400 color image with 8 bits per color component.
img.fill(0); // Set pixel values to 0 (color : black)
unsigned char purple[] = { 255,0,255 }; // Define a purple color
img.draw_text(100,100,"Hello World",purple); // Draw a purple "Hello world" at coordinates (100,100).
img.display("Window Title"); // Display the image in a display window.
img.save_png("test.png"); // Save as PNG to prove we linked correctly
img.save_jpeg("test.jpg"); // Save as JPG to prove we linked correctly
return 0;
}
Your CMake CmakeLists.txt
inside CLion
will be something like this:
cmake_minimum_required(VERSION 3.6)
project(CImgProject)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(CImgProject ${SOURCE_FILES})
# You can alter these according to your needs, e.g if you don't need to display images - set(YOU_NEED_X11 0)
set(YOU_NEED_X11 1)
set(YOU_NEED_PNG 1)
set(YOU_NEED_JPG 1)
if(${YOU_NEED_X11} EQUAL 1)
message(STATUS "Looking for X11...")
find_package(X11 REQUIRED)
include_directories(${X11_INCLUDE_DIR})
target_link_libraries(CImgProject ${X11_LIBRARIES})
else()
target_compile_definitions(CImgProject PRIVATE cimg_display=0)
endif()
if(${YOU_NEED_JPG} EQUAL 1)
message(STATUS "Looking for libjpg...")
find_package(JPEG REQUIRED)
include_directories(${JPEG_INCLUDE_DIR})
target_link_libraries (CImgProject ${JPEG_LIBRARY})
target_compile_definitions(CImgProject PRIVATE cimg_use_jpeg=1)
endif()
if(${YOU_NEED_PNG} EQUAL 1)
message(STATUS "Looking for libpng...")
find_package(PNG REQUIRED)
include_directories(${PNG_INCLUDE_DIR})
target_link_libraries (CImgProject ${PNG_LIBRARY})
target_compile_definitions(CImgProject PRIVATE cimg_use_png=1)
endif()
Here is my, rather disappointing, image after all that!
#define cimg_display 0
before includingCImg.h
. – Appall