Ok it's the third time I write this message. it's too late for me…
I wanted to improve this a little and found a workaround:
It has some limitation due to OutOfMemoryError (handled with try/catch) and slow down a bit on too large images (full HD), but it doesn't skip frames…
basically there's an ArrayList of PImages ( a store ) keeping a copy of every frame and a FrameSaver instance looking at it.
hit ' r ' to start adding images onto the store and start the FrameSaver
hit ' r ' again to stop adding frames to the store and to tell FrameSaver to prepare himself to quit, the quit() method is called from within the run() method, because a call at it when re-pressed ' r ' key could cause the saver not to save every frame we wanted to.
some further improvement could be erasing image from the store when saved, but have to mess with CurrentModificationException
or
Use two arrays filled with a certain amount of images alternatively (e.g. first store: img from 0 to 99, second store with img from 100 to 199, then the first aging with img from 200 to 299 and so on) and feed the Saver switching form one store to another when all images are saved).
And also we could find a way to prevent the sketch to close if the store contains unsaved images, maybe overriding void stop(), but I don't know ho to do it.
Hope this can help.
here's the code:
- class FrameSaver extends Thread {
- boolean running;
- ArrayList<PImage> store;
- int indexSaved;
- int index;
- boolean canQuit;
- public FrameSaver (ArrayList<PImage> s) {
- store = s;
- running = false;
- index = 0;
- indexSaved = 0;
- println("\nREADY TO GO !!!\npress 'r' to start recording");
- }
- public void start() {
- canQuit = false;
- running = true;
- index = frameCount+1;//because it will start saving on the next frame
- println("recording frames from frame # "+ index);
- indexSaved = 0;
- try {
- super.start();
- }
- catch(java.lang.IllegalThreadStateException itse) {
- println("cannot execute! ->"+itse);
- }
- }
- public void run() {
- while (running) {
- if (store.size()>indexSaved) {
- try {
- store.get(indexSaved).save(dataPath("fromArrayList/frame"+nf(index, 3)+".tiff"));
- index++;
- indexSaved++;
- }
- catch(Exception e) {
- println("error with "+e);
- }
- }
- else {
- quit();
- }
- }
- }
- public void quit() {
- if (canQuit) {
- println("now executing quit() !");
- running = false;
- interrupt();
- canQuit = false;
- imgStore = new ArrayList<PImage>();
- fs=new FrameSaver(imgStore);
- }
- }
- }
- FrameSaver fs;
- ArrayList<PImage> imgStore;
- boolean recording = false;
- void setup() {
- size(1920/2, 1080/2);
- imgStore = new ArrayList<PImage>();
- fs = new FrameSaver(imgStore);
- textSize(120);
- frameRate(500);
- }
- void draw() {
- background(0);
- text("frame # "+nf(frameCount, 3), 20, height/2);
- text("fps = " + int(frameRate), 20, 140);
- if (recording) {
- try{
- imgStore.add(get());
- }
- catch(OutOfMemoryError e){
- println("\t"+e);
- recording = false;//to stop trying to add images
- fs.canQuit = true;// to tell the FrameSaver it can quit from within his run method
- println("now forcing to stop recording, at frame " +frameCount);
- }
- }
- }
- void keyPressed() {
- if (key=='r') {
- if (!fs.running) {
- fs.start();
- recording = true;
- }
- else if(recording){
- println("we finished recording at frame # "+frameCount);
- recording = false;
- fs.canQuit = true;
- }
- }
- }