Fast read colors out of an image

I’ve got an image and I want to assign its pixel colors to points on a mesh. I’m doing this by populating and passing an array of colors (ofColor, to be exact).

To the ofImage, I’m doing

ofPixels_<unsigned char> curPixels = image.getPixels();
ofColor* colors = new ofColor[w * h];
for (unsigned y = 0; y < h; ++y){
    for (unsigned x = 0; x < w; ++x){

		unsigned i = y*w + x;			
			colors[i] = curPixels.getColor(x, y);
			
	}
}
meshHolder.setColors( colors );
delete[] colors;

In the meshHolder i just go iterate through the vertices and populate the colors: meshHolder::setColors( ofColor* inColors ):

for (unsigned i = 0; i < numPoints && i < numVertices; ++i){

		mesh.setColor(i, colors[i]);

}

This is pretty slow, it drops me down from 60fps to 30 fps. Is there a way to just read at once all the colors out? A problem I will eventually have is that I won’t want to read it out sequentially but I’d like to take a subsection of the image and sample it (like say every other pixel or something).

I don’t think the setting of the colors is slowing me down, just doing getColor(x,y) takes a long time.

Is there a way to draw a subsection to FBO and then consecutively read all the pixel colors out simultaneously? Is there a better way to assign all the colors to a mesh? I don’t want to bind a texture during draw because of stuff that’s going on in my shader.

the way you are reading the colors is really slow, it uses a lot of multiplications to calculate the pixel index from x,y every time.

also allocating and deleting memory like that on every frame is not a very good idea, you should just write directly to the mesh.

and this:

ofPixels_<unsigned char> curPixels = image.getPixels();

is making a full copy of the pixels every frame which will slow down things a lot.

if you are using the nightly builds you can do:

ofPixels & pixels = image.getPixels();
mesh.getColors().resize(pixels.getWidth()*pixels.getHeight());
int i = 0;
for(auto line: pixels.getLines()){
    for(auto pixel: line.getPixels()){
        mesh.getColors()[i].set(pixel[0],pixel[1],pixel[2])
        i++;
    }
}

but in general solving those issues in any way would help.

3 Likes