Using libgmic
libgmic is a small, portable, thread-safe, multi-threaded, C++, image processing library that forms the foundation of the G'MIC framework. It is used by all available G'MIC interfaces. It is built upon the CImg Library, a lower-level C++ template image processing library which actually implements the core algorithms that G'MIC uses (a.k.a the native commands). Despite its small size (approx. 5 MB ), libgmic provides even more image processing operators than CImg, as well as a simpler API, so that anyone can readily integrate all the G'MIC features directly into their own code.
Here is a quick step-by-step guide to show how such an integration could be achieved. It assumes you are using Linux, but of course, the steps are very similar for other operating systems.
//----- File 'foo.cpp' -----
#include "gmic.h"
#include <cstdio>
int main() {
try {
gmic("testimage2d 512 output gmic_test.png");
} catch (gmic_exception& e) { // In case something went wrong:
std::fprintf(stderr,"ERROR : %s\n",e.what());
return -1;
}
return 0;
}
$ g++ -o foo foo.cpp -lgmic
$ ./foo
Additional information:
//----- File 'foo2.cpp' -----
#include "gmic.h"
#include <cstdio>
#include <cmath>
int main() {
gmic_list<float> image_list;
image_list.assign(2); // Tell 'image_list' it has 2 images.
for (unsigned int i = 0; i<image_list._width; ++i) { // 2 input images.
// Initialize each image of 'image_list' to a 320x200x1x3 (color) image.
gmic_image<float>& img = image_list[i];
img.assign(320,200,1,3);
// Fill image buffer with random sinus waves.
float *ptr = img;
for (unsigned int c = 0; c<img._spectrum; ++c) // 3 channels.
for (unsigned int y = 0; y<img._height; ++y) // 200 rows.
for (unsigned int x = 0; x<img._width; ++x) // 320 columns.
*(ptr++) = (float)(128 + 127*std::cos(x/(5. + 10*i))*std::sin(y/(5. + 10*i + c)));
}
gmic_list<char> image_names; // We don't care about image names here, let this empty.
try {
gmic("water[0] 20 flower[1] 20 blend vividlight",
image_list,image_names);
} catch (gmic_exception &e) { // In case something went wrong.
std::fprintf(stderr,"ERROR : %s\n",e.what());
return -1;
}
// Here, 'image_list' now contains only 1 (color) image of size 320x200x1x3.
// You can retrieve the image data from the buffer at 'image_list[0]._data',
// as well as the image dimensions 'image_list[0]._xxxx', where
// 'xxxx' can be 'width', 'height', 'depth' or 'spectrum'.
(...) // Do whatever you want with the image data here.
image_list.assign(0); // Deallocate images, if you want to do it before the destructor.
return 0;
}
In foo2.cpp, we first define and initialize a list of two input images (with random sinus waves for the colors). They actually look like this:
At this stage, you already know the most complex things about the use of the libgmic API :).
R(0,0),R(1,0),R(0,1),R(1,1),G(0,0),G(1,0),G(0,1),G(1,1),B(0,0),B(1,0),B(0,1),B(1,1)
gmic g_instance;
g_instance.run("water[0] 20",image_list,image_names);
g_instance.run("flower[1] 20",image_list,image_names);
g_instance.run("blend vividlight",image_list,image_names);
g_instance.run("output gmic_test.png",image_list,image_names);
const char *const name1 = "First image", *const name2 = "Second image";
gmic_list<char> image_names;
image_names.assign(2);
image_names[0].assign(std::strlen(name1)+1); // We don't forget the '\0'.
std::strcpy(image_names[0],name1);
image_names[1].assign(std::strlen(name2)+1); // We don't forget the '\0'.
std::strcpy(image_names[1],name2);
const char *const output_name = image_names[0];
//----- File 'foo3.cpp' -----
#include "CImg.h"
#include "gmic.h"
using namespace cimg_library;
int main() {
// Load input image files, using the CImg Library.
CImg<float>
img1("img/lena.jpg"),
img2("img/joconde.jpg");
// Move input images into a list.
CImgList<float> image_list;
img1.move_to(image_list);
img2.move_to(image_list);
// Define the corresponding image names.
CImgList<char> image_names;
CImg<char>::string("First image").move_to(image_names);
CImg<char>::string("Second image").move_to(image_names);
// Invoke libgmic to execute a G'MIC pipeline.
gmic("water[0] 15 wave[1] 15 "
"320,256 mandelbrot. -0.6918,-0.4831,-0.6375,-0.4338,256 "
"64,1,1,3,?(255) r. 256,1,1,3,3 point. 0 map.. . rm. "
"frame 2,2,0 to_rgba drop_shadow 3,3 montage X "
"i[0] 100%,100%,1,3,255 blend alpha "
"name \"Result image\"",
image_list,image_names);
// Display resulting image.
const char *const title_bar = image_names[0];
image_list.display(title_bar);
return 0;
}
In the G'MIC source, you will a sample file use_libgmic.cpp which contains all the stuffs we've summarized in this page. Check it out and compile it to have another example on how the libgmic can do for you.
G'MIC is an open-source software distributed under the
CeCILL free software licenses (LGPL-like and/or
GPL-compatible).
Copyrights (C) Since July 2008,
David Tschumperlé - GREYC UMR CNRS 6072, Image Team.