1

I am using openimageIO to read and display an image from a JPG file, and I now need to store the RGB values in arrays so that I can manipulate and re-display them later.

I want to do something like this:

         for (int i=0; i<picturesize;i++) 
        { 
          Rarray[i]=pixelredvalue; 
          Garray[i]=pixelgreenvalue; 
          Barray[i]=pixelbluevalue;
        } 

This is an openimageIO source that I found online: https://people.cs.clemson.edu/~dhouse/courses/404/papers/openimageio.pdf

"Section 3.2: Advanced Image Output" (pg 35) is the closest to what I'm doing, but I don't understand how I can use the channels to write pixel data to arrays. I also don't fully understand the difference between "writing" and "storing in an array". This is the piece of code in the reference that I am talking about:

        int channels = 4;
        ImageSpec spec (width, length, channels, TypeDesc::UINT8);
        spec.channelnames.clear ();
        spec.channelnames.push_back ("R");
        spec.channelnames.push_back ("G");
        spec.channelnames.push_back ("B");
        spec.channelnames.push_back ("A");

I managed to read the image and display it using the code in the reference, but now I need to store all the pixel values in my array.

Here is another useful piece of code from the link, but again, I can't understand how to retrieve the individual RGB values and place them into an array:

#include <OpenImageIO/imageio.h>
OIIO_NAMESPACE_USING
...
const char *filename = "foo.jpg";
const int xres = 640, yres = 480;
const int channels = 3; // RGB
unsigned char pixels[xres*yres*channels];
ImageOutput *out = ImageOutput::create (filename);
if (! out)
return;
ImageSpec spec (xres, yres, channels, TypeDesc::UINT8);
out->open (filename, spec);
out->write_image (TypeDesc::UINT8, pixels);
out->close ();
ImageOutput::destroy (out);

But this is about writing to a file, and still does not solve my problem. This is on page 35.

elan95
  • 9
  • 3
  • My question was flagged as unclear, so I tried to clarify it here. I'm very new to stackexchange and this library, and I would appreciate constructive criticism. I don't have a lot of programming experience. Please tell me what I am doing wrong. – elan95 Feb 11 '18 at 22:18
  • 1
    Please edit your original question instead of asking a new one. Then please format all your code blocks property. It is still completely unclear what the relation to opengl is. It is also unclear how you currently read the image. – BDL Feb 11 '18 at 22:24
  • I will go ahead and delete the old question since it is confusing. I am using openGL for this, so I thought it was pertinent. Like maybe some gl pixel functions can be used to take in and store the data? To read the image, I used this guy's code: https://stackoverflow.com/questions/34936418/cant-display-a-png-using-glut-or-opengl (I am not needing a png, so his question isn't relevant. His code is built off of what's in the book in the "read image" section) – elan95 Feb 11 '18 at 22:37
  • My problem is accessing the RGB values. I don't need help with storing values, etc. OIIO uses "channels", and I am very confused on how I can use a "channel" of a pixel and get its R,G,and B values into my own arrays. – elan95 Feb 11 '18 at 22:39
  • @Rabbid76, well what I'm doing is creating 3 simple arrays. As for the channel used in OIIO, I don't understand it myself, and was hoping someone did. This is what the source talks about, but it does not define the channel: "Color information is always in the order R, G, B, and the alpha channel, if any, always follows RGB, and Z channel (if any) always follows alpha. So if a file actually stores ABGR, the plugin is expected to rearrange it as RGBA." – elan95 Feb 11 '18 at 22:49

1 Answers1

1

Let's assume, that your code which reads an image, looks like this (snippet from OpenImageIO 1.7 Programmer Documentation, Chapter 4.1 Image Input Made Simple, page 55):

ImageInput *in = ImageInput::open (filename);

const ImageSpec &spec = in->spec();
int xres = spec.width;
int yres = spec.height;
int channels = spec.nchannels;
std::vector<unsigned char> pixels (xres*yres*channels);
in->read_image (TypeDesc::UINT8, &pixels[0]);
in->close();
ImageInput::destroy (in);

Now all the bytes of the image are contained in std::vector<unsigned char> pixels.

If you want to access the RGB valuse of the pixel at positon x, y, the you can do it like this:

int pixel_addr = (y * yres + x) * channels;

unsigned char red   = pixels[pixel_addr]; 
unsigned char green = pixels[pixel_addr + 1]; 
unsigned char blue  = pixels[pixel_addr + 2]; 

Since all the pixels are stored in pixels, there is no reason to store them in separate arrays for the 3 color channels.
But if you want to store the red, green and blue values in separated arrays, then you can do it like this:

std::vector<unsigned char> Rarray(x_res*yres);
std::vector<unsigned char> Garray(x_res*yres);
std::vector<unsigned char> Barray(x_res*yres);

for (int i=0; i<x_res*yres; i++) 
{ 
    Rarray[i] = pixels[i*channels]; 
    Garray[i] = pixels[i*channels + 1]; 
    Barray[i] = pixels[i*channels + 2];
} 

Of course the pixels have to be tightly packed to pixels (line alignment of 1).

Rabbid76
  • 202,892
  • 27
  • 131
  • 174