0

In the documentation (http://cimg.eu/reference/structcimg__library_1_1CImg.html#a24f3b43daa4444b94a973c2c3fff82c5), you can read that the N°7 constructor requires an array of values to fill the image :

values = Pointer to the input memory buffer.

You must know that I'm working with a RGB 2D image (so, a "normal"/"common" image).

Thus, I filled a vector (= more or less an array) with Nx3 values. N is the number of pixels, and the number "3" is because I use red, green and blue. I set the first value to 0, the 2nd to 0, the 3rd to 255 and these 3 operations are repeated N times. That's why my vector, which is named w, looks like that : {0, 0, 255 ; 0, 0, 255 ; etc.}

I wrote this constructor : cimg_library::CImg<unsigned char>(&w[0], width, height, 2, 3); to say that there are 3 channels, a depth of 2 (since I use 2D), and to give my values (width, height and pixels).

I should obtain a entirely blue image. But it's yellow. Why ? Did I badly used the vector ?

JarsOfJam-Scheduler
  • 2,809
  • 3
  • 31
  • 70

1 Answers1

2

Unlike most formats which are stored "band interleaved by pixel", i.e. RGBRGBRGB..., the data in a CImg are stored "band-interleaved by plane", i.e. all the red components are first, then all the green components, then all the blue ones, so it looks like RRRGGGBBB. This is described here.

So, your code would need to be like this:

#include <vector>
#include "CImg.h"

using namespace std;
using namespace cimg_library;

int main()
{
    const int width=3;
    const int height=2;
    // 1. row - red, green, blue
    // 2. row - cyan, magenta, yellow

    // 6 pixels
    // Red plane first - red, green, blue, cyan, magenta, yellow
    // 255,0,0,0,255,255
    // Green plane next - red, green, blue, cyan, magenta, yellow
    // 0,255,0,255,0,255
    // Blue plane - red, green, blue, cyan, magenta, yellow
    // 0,0,255,255,255,0

    vector<unsigned char> w{
       255,0,0,0,255,255,
       0,255,0,255,0,255,
       0,0,255,255,255,0
    };

    CImg<unsigned char> image((unsigned char*)&w[0],width,height,1,3);
    image.save_pnm("result.pnm");
}

enter image description here


Or, if you simply want a solid blue image, the easiest way is probably to instantiate a simple 1x1 blue image using an initialiser for the one pixel, then to resize it:

    // Instantiate a 1x1 RGB image initialised to blue (last three values)
    CImg<unsigned char> blue(1,1,1,3,0,0,255);
    // Resize to larger image
    blue.resize(width,height);

Another method might be:

// Create RGB image and fill with Blue
CImg<unsigned char> image(width,height,1,3);
image.get_shared_channel(0).fill(0);
image.get_shared_channel(1).fill(0);
image.get_shared_channel(2).fill(255);

Another method might be:

CImg<unsigned char> image(256,256,1,3);

// for all pixels x,y in image
cimg_forXY(image,x,y) {
    image(x,y,0,0)=0;
    image(x,y,0,1)=0;
    image(x,y,0,2)=255;
}
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432