Problem animating colour output from image pixel by pixel

Hi

I’m new to openFrameworks and finding it difficult to get going.

I want to read each pixel from an image, get the colour and use that to fill a rectangle so the colour of the rectangle changes as the program loops through the image pixels.

So far my colour variable colorAtXY changes as it should in the update section, but the values are not passed through to the draw section a the draw only happens after the update loop has completed.

When the rectangle is finally drawn the colour variable fills it with black, which is not a colour used in the original image.

If I try drawing within the update loop no rectangle appears.

Please can someone point me in the right direction.

Thanks
G.

#include “ofApp.h”

//--------------------------------------------------------------
void ofApp::setup(){

myImage.load("slab7.jpg");
myImage.setImageType(OF_IMAGE_COLOR_ALPHA);
colorAtXY = ofColor(0,0,0);
ofSetFrameRate(60);

}

//--------------------------------------------------------------
void ofApp::update(){

int w = myImage.getWidth();
int h = myImage.getHeight();

for(int y=0; y<h; y++) {
    for(int x=0; x<w; x++) {
        // Extract the color components of the pixel at (x,y)
                
        ofColor colorAtXY = myImage.getColor(x, y);
        
        std::cout << "x: " << x << endl;
        std::cout << "y: " << y << endl;
        
        ofFill();
       
    }
}

}

//--------------------------------------------------------------
void ofApp::draw(){

ofSetColor(colorAtXY);
ofDrawRectangle(700, 0, 100, 100);

}

Hi!

There’s a few things I want to clarify, before I answer your specific question, just to be sure.

Unless you are going to play with the alpha channel of an image later on, there’s no need to call setImageType. OF does that for you.

The default vale for frame rate is 60, which still is the most common frame rate. OF will try to keep up with that in the refresh cycle. You only need this function, if you want to lower the frame rate. Or if you set the vertical sync off.

You are right, if you draw call ofDrawRectangle in update it won’t appear on the window. That’s because update is used for updates/calculus and draw to display things on the screen.

Now, to your question… The reason your square is black, it’s because you are declaring a new variable inside your loop. Where you have:

    ofColor colorAtXY = myImage.getColor(x, y);

You should have:

    colorAtXY = myImage.getColor(x, y);

But, even so, this would not solve your problem. Because you will only get the last colour of your image. The bottom left one.

OF calls update and then draw. So, what you are doing is going through all the colours and then drawing one square with the last colour assigned.

If you want to go through all the colours and display them, you will have to do something like this:

setup

myImage.load("slab7.jpg");  

w = myImage.getWidth();
h = myImage.getHeight();

x = 0;
y = 0;

colorAtXY = ofColor(0,0,0);

update

x++;
if (x == w))
{
    x = 0;
    y++;
    if (y == h) y = 0;
}

colorAtXY = myImage.getColor(x, y);

draw

ofSetColor(colorAtXY);
ofDrawRectangle(50, 50, 100, 100);

ofSetColor(ofColor::black);
ofDrawBitmapString(x, 200, 75);
ofDrawBitmapString(y, 200, 100);

ofDrawBitmapString("Max value: " + ofToString(w), 250, 75);
ofDrawBitmapString("Max value: " + ofToString(h), 250, 100);

Play around and if have any questions, fell free to ask! :slightly_smiling:

Thanks that’s really great. You’ve made it very clear. Now I can have some :relaxed: fun!