Cimg – The Cool IMAge library – Intro Tutorial

Cimg is a nice and simple image library. What I especially like about it is that it is not fussy and does just what is required – it can load/save many different types of images, provides quite a few very useful built-in functions and provides direct access to individual pixels.

lenas.jpg

The following piece of code loads lena – the muse of all image computer scientists – seperates the red, green and blue channel and finally saves the red one as lenaRed.png

#include <iostream>
#include "CImg.h"
using namespace cimg_library;
using namespace std;
int main() {
    // Create 4 images - imgLena: a jpg image loaded - imgR, imgG & imgB:
    //                       4 blank images of X, Y, Z, v, fill
    // X-width of image, Y-height of image, Z-depth of image, since 2D Z=1,
    //                       v-number of colours, fill-colours to fill with
    CImg<unsigned char> imgLena("lena.jpg"),
        imgR(128,128,1,3,0),
         imgG(128,128,1,3,0),
         imgB(128,128,1,3,0);
    // for all pixels x,y in imgLena
    cimg_forXY(imgLena,x,y) {
        imgR(x,y,0,0) = imgLena(x,y,0,0),    // Red component of imgLena sent to imgR
        imgG(x,y,0,1) = imgLena(x,y,0,1),    // Green component of imgLena sent to imgG
        imgB(x,y,0,2) = imgLena(x,y,0,2);    // Blue component of imgLena sent to imgB
    }

    // 4 display windows, one for each image
    CImgDisplay main_disp(imgLena,"Original"),
        draw_dispR(imgR,"Red"),
        draw_dispG(imgG,"Green"),
        draw_dispB(imgB,"Blue");

    // wait till window is closed
    while (!main_disp.is_closed){
        main_disp.wait();
        cout << main_disp.mouse_x << "," << main_disp.mouse_y << endl;    // display the coordinates of the mouse  
    }
    imgR.save_png("lenaRed.png");            // saving an image as png
    return 0;
  }

More info is available at http://cimg.sourceforge.net/.

19 responses to “Cimg – The Cool IMAge library – Intro Tutorial

  1. Hi,
    When I insert the code:
    CImg image(“lena.jpg”);
    I get always the error:
    ===============================
    c:\glut\include\im\cimg.h(6936) : fatal error C1076: compiler limit : internal heap limit reached; use /Zm to specify a higher limit
    c:\glut\include\im\cimg.h(23596) : see reference to class template instantiation ‘cimg_library::CImg’ being compiled
    c:\glut\include\im\cimg.h(23538) : while compiling class-template member function ‘struct cimg_library::CImgList &__thiscall cimg_library::CImgList::load_cimg(struct _iobuf *const ,const char *const )’
    ==============================
    Can you help me? Thanks so much

  2. Thanks, i was getting the same problem as HUYNH HUU HUNG. working fine now. can you help please, i need a simple example code of how to apply a filter,let’s say sobel if possible.

  3. hello. i tried to run the example on the main site but it’s not working for me 😦
    I’m using Visual C++ 2005 express ed., done everything to add libs from the SDK /which they say is required/ and when i’m running:

    #include “stdafx.h”
    #include “CImg.h”
    using namespace cimg_library;

    int main() {
    CImg image(“F.jpg”);

    i’m getting 20 errors simillar to this one:
    error LNK2019: unresolved external symbol __imp__DestroyWindow@4 referenced in function “public: struct cimg_library::CImgDisplay & __thisc (….)

    could you help me please? Is there a ‘what to do for dummies’ manual how to get this library working?

  4. #include “stdafx.h”
    #include “CImg.h”

    maybe try
    #include “windows.h”
    #include “CImg.h”

    But this is simply a hunch… Well, back to looking
    for how to use, or whether to use, CImgList
    instead of an array of CImg’s or the CImg as
    a member in a struct and then array… 🙂

    Shaggy Buffalo

  5. Yes, I agree with you that is a quite simple problem to solve. But why he posted it on internet?

  6. how do i compare the values of two pixels in two images? I think i have the code correct but still cannot get it to work.

    m code has:
    for(..){
    if (img1(x,y) != img2(x,y)){ …}
    }

    also, if I want to cout the value of a pixel, would I do cout << img1(x,y); ? When I do this I get output of “H” for each pixel, even though my picture has many different colors.

  7. Hi, Im a new user of CImg trying to compile the Tutorial program from this site using DevCpp. Unfortunately during compile, I come accross an error saying segmentation fault.
    Can you guys help me compile the program?

  8. I’ve loaded a cimg instance with a small PNG that’s
    2000×1000 and only 88kb filesize. This works fine. I now
    am trying to load a PNG that’s 14,000×11,000 and the
    PNG is 43 megabytes. 🙂 Now Paintshop Pro handles this
    just fine, but I load this in my app and it blows up.
    System gets very slow. Takes a long time to load, like 4 min
    as apposed to Paintshop Pro’s 15 sec!? Then it actually
    loads and displays the whole huge image in my small window,
    but RAM has gone to my max of 1gB! From 375mB to 1g?
    How is cimg using 625mB for a 43mb image, or 150mb
    as a 1byte BMP, or even 450mB as a 3byte BMP, but 625?

    So my question. Is that a no-no? And is there a way to just
    load a portion of the image. This is a GPS app, so I really only
    need a small bit of the map PNG image.

    Any ideas? And no, I was hoping to avoid having to cut
    the 43mB one into little files.

    Shaggy

  9. I have taken deb package, cimg library files on ubuntu. Now, i have an sample program and i m tring to compile it on ubuntu using gcc compiler. but i m not getting actually how to include those library files while compiling.

  10. CImg is designed to hold images in memory completely. Therefore, the PNG you are loading is decompressed and stored fully in memory (about 4 (or 3) x 14,000 x 11,000 bytes) I believe.

  11. I’m making program with CImg, is there any function that can convert RGB image to grayscale (in CImg)? if not, how can iget the grayscale image?

    Thank you for your response!

  12. Simply calculate the medium value of R G and B and set the new RGB value to [medium, medium, medium]…

      • int main(int argc, char *argv[]) {
        CImg image(argv[1]);
        int w = image.width();
        int h = image.height();
        cout << w << "x" << h << endl;
        for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
        double lum = (double)image(j,i,0,0)*0.299 + (double)image(j,i,0,1)*0.567 + (double)image(j,i,0,2)*0.114;
        image(j,i,0,0) = (unsigned char)lum;
        image(j,i,0,1) = (unsigned char)lum;
        image(j,i,0,2) = (unsigned char)lum;
        cout << "(" << i << "," << j << ") =" << " R" << (int)image(j,i,0,0) << " G" << (int)image(j,i,0,1) << " B" << (int)image(j,i,0,2) << endl;
        }
        }

  13. You really make it seem so easy with your presentation but I find this matter to be really something which
    I think I would never understand. It seems too complex and very broad for me.
    I am looking forward for your next post, I’ll try to get the hang of it!

  14. CIMG library sucks to the core. I have done everything possible, i have installed imagemagick, included libraries but cannot make it run in code blocks.everytime i run i get a error saying jpen format is not recognizable.

Leave a comment