G'MIC as a Cpp 32bit float image processing library - GreycLab/gmic-community GitHub Wiki
- Getting Started
G'MIC also provides the option to compile as a C++ library - it's one of the build targets in the source archive Makefile - meaning you can apply G'MIC commands on your program's internal image data. This means instead of writing lengthy code in C++ for a complex pipeline you can instead just pass it to a gmic call, internally. Also potentially you could include all of the filters written in G'MIC script (yes, even the ones from the G'MIC GIMP plugin!) although that's beyond the scope of this article.
Here is a brief example of just how easy it is:
/*
File: example1.cpp
Note : To compile this example with g++ use :
g++ -o example1 example1.cpp -lgmic -lfftw3
*/
#include "gmic.h"
int main()
{
// Create an image list, and an image names list
gmic_list<float> images;
gmic_list<char> images_names;
try
{
// Run a G'MIC command on the provided lists
gmic("test.bmp -gradient_norm -b 3 -n 0,255 -o file.bmp",images,images_names);
}
catch (gmic_exception &e)
{
// Use G'MIC exceptions to capture failures
std::fprintf(stderr,"\n- Error encountered when calling G'MIC : '%s'\n",e.what());
return 0;
}
// Clear the image lists
images.assign(0);
return 0;
}
The above code was adapted from the example program gmic_use_lib.cpp packaged with the G'MIC source code under CeCILL v2.0 license
- Accessing the image data
That looks easy enough, but you may be wondering how you can get at the image data. Well fortunately that's very simple as well, you can obtain properties of any image in the list as well as a pointer to the image data:
std::printf("Number of images in the list: %u", images._width);
std::printf("Width of first image: %u", images._data[0]._width);
std::printf("Height of first image: %u", images._data[0]._height);
std::printf("Address of first image buffer: %p", images._data[0]._data);
It's important to note images._data points to the image list, whereas images._data[0]._data points to the first pixel of an actual image. Other image properties include:
_depth : number of image slices in z-direction, usually 1 for a "standard" image.
_spectrum : number of image channels, usually 3 for a standard RGB image.
Now there is one more thing you need to know about the image data and that's the memory layout. If you've read anything about G'MIC script you will know it treats images as a set of channels (for example red, green, blue). Well that's also how it's arranged in memory; for an RGB image it's a single flat array of all the red pixels, then all the green pixels and finally the blue pixels.
- Manipulating the image list
At some point you might need to change the number of images in the list or create your own from scratch. It's very straightforward to set the list size and you can set individual images using the gmic_image structure:
images.assign(5);
gmic_image<float>& img = images._data[0];
img.assign(256,256,1,3);
The above would set the list to 5 empty images (containing no image data), then set the first to be a 256x256, 3 channel buffer - the third parameter refers to z-depth which in this case is 1.
Everything discussed in this article is demonstrated with the gmic_use_lib.cpp program in the G'MIC source archive, so be sure to check it out!