Fastest way to block copy pixels?

what is the fastest way to block copy pixels in an oftexture or ofpixels object?

I want to copy a complete image and move across the x axis a few pixels as a block.
at present i’m iterating through every pixel with getcolor and setcolor which is hugely inefficient.

the method pixelsSource.pasteInto(pixelsTarget, x, y);
is not working for me -
can anyone advise me on a better/ faster way to move around large pixel blocks?

funny how working out how to ask the question helps find the answer…

probably horribly brute force but using loadscreen with a repeating offset increases speed nearly 10x

videoTexture.loadScreenData(camWidth/2, 0, videoPixels.getWidth(), videoPixels.getHeight());

then

    videoTexture.draw(camWidth/2+1, 0); 

there must be a better way - suggestions?

d

Hi. & bump. Also interested. On the gpu side appears that glTexSubImage2D, or glBlitFramebuffer, are the way to go.

I’ve been having lots of improvement on the cpu side by defining pixels in images as 32bit words and lovely bit shifting to achieve lower bandwith & faster speeds with byte precision rgba.

Hi you can either simply load your image into a shader and in it use some specific logic for “copying” the pixels. You can use an ofFbo to render the shader so you then can use re use on the next drawing cycle.
If you simply want to draw it you can draw the texture several times with different subsections.
you can use ofImage's following function

    /// \param x X position to draw cropped image at.
    /// \param y Y position to draw cropped image at.
    /// \param w Width of subsection to draw.
    /// \param h Height of subsection to draw.
    /// \param sx X position in image to begin cropping from.
    /// \param sy Y position in image to begin cropping from.
    void drawSubsection(float x, float y, float w, float h, float sx, float sy) const;

Last thing you can do is simply access the array of data and copy (even using a memcpy, which can be a bit scary if you dont know exactly whats going on)

ofImage img;
img.load(....);

//define an area to copy by a rectangle in the number below!
int x ;
int y;
int w; 
int h;

ofImage imgBlock;
img.getPixels().cropTo(imgBlock.getPixels(),x,y, w, h); 
imgBlock.update();

//or instead you can go much nastier and do a memcpy, but I am a bit tired now to think on the right indices to use. :stuck_out_tongue: hope this is helpful

Would enjoy too see where this goes, other alternatives :wink: see bitshifting performance here


ofImage screenbuffer;
	bool usetexture = true;
	float elapsed;
	float elapsedbit;

	void setup(){
		// screenbuffer.allocate(w,h,OF_IMAGE_COLOR_ALPHA);
		screenbuffer.allocate(w,h,OF_IMAGE_COLOR);
		screenbuffer.setUseTexture(true);
	}
	void keyPressed(int k){ usetexture^=true; screenbuffer.setUseTexture(usetexture);screenbuffer.allocate(w,h,OF_IMAGE_COLOR);}

	void update(){

		ofPixelsRef pixels = screenbuffer.getPixels();
		float nowimgbegin = ofGetElapsedTimef();
		float nowimgend = ofGetElapsedTimef();

		// see setFromPixels ofPixelsRef uses memcpy
		int ntests = numuploadsframe; while(ntests--){

			int i=0; while(i++<wh){
				// pixels.setColor(x,y,
				pixels.setColor(i,
					// ofColor(
					// 	ofRandom(255),ofRandom(255),ofRandom(255)
					// );
					ofColor(
						rand()%(255),rand()%(255),rand()%(255)
					));
			}
		}


		nowimgend = ofGetElapsedTimef();
		elapsed = nowimgend - nowimgbegin;


		nowimgbegin = ofGetElapsedTimef();

		ntests = numuploadsframe; while(ntests--){

			int i=0; while(i++<wh){
				// is this not working??? pixels.setColor(index seems broken)
				// pixels.setColor(i,
				int x = i%w; int y=i/w;
				pix = rand();
				pixels.setColor(x,y,
					ofColor((pix&255), (pix>>8)&255,(pix>>16)&255
					// ofColor((pix), (pix>>8),(pix>>16)
					));
			}
		}

		nowimgend = ofGetElapsedTimef();
		elapsedbit = nowimgend - nowimgbegin;


		screenbuffer.update();
	}