Using libgmic

libgmic is a small, portable, thread-safe, multi-threaded, C++, image processing library that forms the foundation of the framework. It is used by all available interfaces. It is built upon the CImg Library, a lower-level C++ template image processing library which actually implements the core algorithms that 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 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.

Step 1: Get the required library files

To be able to use libgmic in your own code, you need:

Step 2: Write and compile your first code using libgmic

Now, you should be able to write your first libgmic-based program foo.cpp:
        //----- 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;
        }

You can compile it simply like this (here, with g++):
        $ g++ -o foo foo.cpp -lgmic

Execute it:
        $ ./foo

and if all goes well, you should have a new image file gmic_test.png in your current folder, which looks like this:
libgmic

Additional information:

Step 3: Dealing with image buffers

It is quite unlikely you want to manage the input/output of your image data to/from libgmic using files only. So here are details on how to pass image data using memory buffers instead. The important things to know are: This second example foo2.cpp illustrates these points:
        //----- 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:

libgmic
libgmic
Then, the invocation creates this single output image buffer (but without saving the image into a file in this case):
libgmic
This is the result of the following pipeline: 1. Apply a water effect on the first image (command water[0] 20), 2. Apply a flower effect on the second image (command flower[1] 20), and 3. Blend the resulting images together, using the Vivid light mode (command blend vividlight). Easy, isn't it ?

At this stage, you already know the most complex things about the use of the libgmic API :).

Step 4: Additional information about the libgmic API

In bulk order, some other interesting things to know about the libgmic API:

In the 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.