Save frames every X framerate to a GIF file


#1

Hi everyone, the subject is pretty self explanatory. I want to save little moments of the app every X frames into a GIF (ofxGifEncoder). Therefore the code generate severals GIFs files.
The main problem is that while the GIF is being saved, the screen gets frozen until the GIF is totally saved. Once it is saved, the program runs flawlessly.

I´d like to know if there is a way to avoid this effect. This addon is no longer manteined, so I ask the question here.
The code is very hard coded and posted below:

oF: 0.10
OS: Windows 10 64 bits
addon: ofxGifEncoder

A class “helper”, Frame

void Frame::update( ofPixels &video_pixels) {
	load_images();
	imgVideo.setFromPixels(video_pixels.getData(), imgVideo.getWidth(), imgVideo.getHeight(), OF_IMAGE_COLOR);
	
	if (ofGetFrameNum() == 50) {
		imgLogo.load("app2.jpg");
		
		pixels = imgLogo.getPixels();
	}
	
	if (ofGetFrameNum() == 130) {
		imgLogo.load("h.jpg");

		pixels = imgLogo.getPixels();
	}

	if (ofGetFrameNum() == 200) {
		imgLogo.load("twx.jpg");

		pixels = imgLogo.getPixels();
	}	
	
	if (ofGetFrameNum() == 260) {
	
		imgLogo.load("kreckl.jpg");

		pixels = imgLogo.getPixels();
	}
	

}


void Frame::draw(){
	ofSetColor(255, 255, 255);
	ofBackground(0, 0, 0);
	
	if (img_pixels.size() == unsigned(size))
	{
		
        int index = 0;

        		canGrab = true;

        ofFill();

      				for ( int j = 0; j <= (rows+1); j++) {
					
					for ( int i = 0; i <= (columns+1); i++) {												
							
							int x = (i*cellsize);  // x position
							int y = (j*cellsize);  // y position
							int loc = (x + y * imgVideo.getWidth())*3;  // Pixel array location					
																					
														
							int r = pixels[loc] + (pixels[loc])*abs(sin(ofGetFrameNum()))*0.015;  // Grab the color
							int g = pixels[loc+1] + (pixels[loc+1])*abs(sin(ofGetFrameNum()))*0.015;
							int b = pixels[loc+2] + (pixels[loc+2])*abs(sin(ofGetFrameNum()))*0.015;

							ofPushMatrix();
							
							ofTranslate((x*x_factor), y*y_factor, 0);
							ofSetColor(r, g, b, 255); //le da la tinta a la imagen, no cambia color

							int nImages = img_pixels.size();

							index = ofRandom(0, nImages - 1);
							
							//Draw a mosaic of images	
							img_pixels[index]->draw(0, 0, (cellsize*x_factor), cellsize*y_factor);								
							
							ofPopMatrix();
							
							
					}
				}				
				
				
	}
	 
}

ofApp.cpp

void ofApp::setup() {
	camWidth = 320;//320;
	camHeight = 240;//240;
	 
	
	vidGrabber.listDevices();	
	vidGrabber.setup(camWidth, camHeight);


	ofSetFrameRate(12);  //12

	SCREEN_H = ofGetScreenHeight();
	SCREEN_W = ofGetScreenWidth();


	frame.setup(camWidth, camHeight, SCREEN_W, SCREEN_H);

	
	nFrames = 0;
	

	frameW = ofGetScreenWidth(); 
	frameH = ofGetScreenHeight();
		
	
	gifEncoder.setup(frameW,frameH , .25, 256);
	
	ofAddListener(ofxGifEncoder::OFX_GIF_SAVE_FINISHED, this, &ofApp::onGifSaved);
		

}


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

		
	vidGrabber.update();
	if (vidGrabber.isFrameNew()) {
		
		//Draw a mosaic of frames.
		frame.update(vidGrabber.getPixels());
		
	}

}


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

		
	frame.draw();
	captureFrame();	

}

void ofApp::captureFrame() {

	if (((ofGetFrameNum() % 30) == 0) && (ofGetFrameNum() > 0)){
		puedeGrabar = true;
		framesCurr = 0;
	}
	
	if ((puedeGrabar) && (framesCurr <= 6)){
		imgScreen.grabScreen(0, 0, frameW, frameH);
		gifEncoder.addFrame(imgScreen, 0.25);				
	}
	
	if (framesCurr == 18)
	{
		
		gifEncoder.save("test_" + ofToString(cont) + ".gif");
		imgScreen.clear();				
		
		puedeGrabar = false;
		framesCurr = 0;
		cont++;	
		gifEncoder.reset();
		gifEncoder.setup(frameW, frameH, .1, 256);
		gifEncoder.stop(); 			
		
	}

	
	framesCurr++;

}

if I don´t do gifEncoder.stop() (stops the thread) after saving the files, all the frames are saved in the same file regardles how many times I call save(). As if the frame buffer the addons uses , wasn´t cleared.
I find it weird since reset() clears the internal buffer array of the addon, so I took for granted, every call to a save() will grab different images.
I appreciate any hint to improve the approach of this proof of concept.

Thanks!