Getting Started with the CImg Library - Learning Reflection
Author: Tony Fu
Date: August 18, 2023
Device: MacBook Pro 16-inch, Late 2021 (M1 Pro)
Code: GitHub
Reference: Chapter 2.1 - 2.2 Digital Image Processing with C++: Implementing Reference Algorithms with the CImg Library by Tschumperlé, Tilmant, Barra
1. Installing XQuartz (X11 on macOS)
Yes, I lied. I said you only need to include the CImg.h
header file to get started. But that's not entirely true. You also need to install the X11
library, which is used to display images.
The X11
library is used to display images. It is an open-source effort to develop a version of the X.Org X Window System that runs on macOS. You can download the latest version of XQuartz here. Follow the instructions to install it on your machine.
Because X11
is often installs in a non-standard location (/opt/X11). This means that the compiler and linker may not automatically look in this location when trying to find the X11 libraries and include files. So, we need to modified the ~/.zshrc
file (or whatever shell you're using) to add the following lines:
# XQuartz (for CImg)
export LIBRARY_PATH=/opt/X11/lib:$LIBRARY_PATH
export CPATH=/opt/X11/include:$CPATH
This effectively includes the X11
library in the compiler's search path. Don't forget to restart the shell or execute source ~/.zshrc
to apply the changes to the current shell.
2. Installing the PNG Library
If you want to read and save images in .png format, as demonstrated in the upcoming example, you'll need to install the libpng
library. You can install it using Homebrew with the following command:
brew install libpng
You won't need to modify any environment variables for libpng
. When you install libpng
using Homebrew (or another standard package manager), it places the library and include files in standard locations that the compiler and linker already recognize.
3. First Program
To display an image using the CImg library, include the CImg.h
header file and use the CImgDisplay
class. Here's a simple example first_code.cpp
:
#define cimg_use_png
#include "CImg.h"
using namespace cimg_library;
int main()
{
CImg<unsigned char> img("../images/lighthouse.png");
img.display("Lighthouse");
return 0;
}
The CImg
class is a template class that represents an image. The template parameter specifies the type of the image pixels. In this case, the image is a color image with unsigned 8-bit integer pixels. The CImg
class has a constructor that takes a filename as input and loads the image from the file. The display()
method of the CImg
class displays the image in a window. The first argument is the title of the window.
Here the macro cimg_use_png
is used to specify that the libpng
library should be used to read and write images in .png format. This gives us a peak into how we can customize the CImg library to suit our needs.
To compile the program, you need to link the X11
and png
library. Here is the command I used:
g++ -o first_code first_code.cpp -lX11 -lpthread -lpng
The -lpthread
option links the pthread
library. The pthread
library is used to create threads, which is needed by the CImg
library.
To run the program, do the following:
./first_code
4. Visual Studio Code Configuration
If you're coding inside Visual Studio Code like I am, you might see a red squiggly line under #include "CImg.h"
, accompanied by the complaint Cannot open source file "X11/Xlib.h" (dependency of "CImg.h")
. Here's how to fix this issue:
-
Open the Command Palette by pressing
Cmd+Shift+P
on a Mac orCtrl+Shift+P
on Windows/Linux. -
Type "C/C++" in the Command Palette, and then select "Edit Configurations (JSON)" from the dropdown list. This action will open the
c_cpp_properties.json
file directly. -
Add the following line to the
includePath
array:
"includePath": [
"${workspaceFolder}/**",
"/opt/X11/include/**" // Add this line
],
- Save the file. The red squiggly line should now disappear.