elan95
elan95

Reputation: 9

How can I use openimageIO to store RGB values in arrays? (using C++, OpenGL)

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.

Upvotes: 1

Views: 1002

Answers (1)

Rabbid76
Rabbid76

Reputation: 211249

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).

Upvotes: 1

Related Questions