Recording into PDF is stopped at specific frame count

Hello all.

I am trying to solove this problem almost 1.5 day… but not solved yet…
If there is someone who has any knowledges, please share the solution.


Problem

Recording into PDF always stops at specific frame count.
DrawLoop animation on window stops as well.
The specific frame count depends on numbers of ball objects.


What I want to do

I want to export many frames into one file with screen display.
At least, I want to export 10,000 ~ 20,000 frames into one file.
This PDF is for printing A1 size poster.


What I want to draw

I want to fill window with bunch of color balls using with ArrayList objects.
ArrayList objects are initialize each 1,000 frame,
then balls start to fill window over again from initialized random positions.

46

What I did for solving ( but not solved yet)

(1) Changing memory setting from IDE preference.

(2) Clearing ArrayList per 1000frame.

(3) Testing both enviroment / iMac(2012/27icn with 32G memory) and Window10(Dell XPS15 with 32G memory)

(4) Changing number of balls ( 750 / 1,500 / 3,000 )

For instance, numbers are like below. Specific number of balls are stopped drawing and exporting at specific frame count.

・750 balls are stopped at about 6,000 frame.
・1500 balls are stopped at about 3,000 frame.
・3000 balls are stopped at about 1,500 frame.

(5) Comented out the lines which relate PDF recording.
In this case, while I coment out the lines which relate PDF, recording is not never stopped! but It can’t acheve recording PDF…


My code

Here is my code which modified simpler and used for test.

import processing.pdf.*;

ArrayList<Ball> balls = new ArrayList<Ball>();
int ballNum = 750;
boolean  record;

//-----------------------------------------------
void setup(){
  size(500,500);
  frameRate(120);  
  beginRecord(PDF, "../export/test.pdf");
  
  for(int i = 0; i<ballNum; i++){
    balls.add(new Ball());
  }
}
//-----------------------------------------------
void draw(){
  for( Ball b : balls ){
    b.show();
    b.move();
  }
  
  if(frameCount%1000 == 0) {
    balls.clear(); 
    for(int i = 0; i<ballNum; i++){
      balls.add(new Ball());
    }   
  }
  println("frameCount /", frameCount);
}

class Ball {
  PVector pos, vel;
  float r;
  
  Ball(){
    pos = new PVector(random(width), random(height));
    vel = new PVector(random(-2,2), random(-2,2));
    r = random(5, 10);
  }
  
  void show(){
    noStroke();
    fill(random(255), random(255), random(255), random(255));
    circle(pos.x, pos.y, r);
  }
  
  void move(){
    pos.x += vel.x;
    pos.y += vel.y;
  }
}

void keyPressed(){
  if (key =='p' || key =='P') record = true; 
}


Thanks a lot for reading and your time.

1 Like

I am pretty sure I misread your problem, inside of the details thing is what I originally said

oops

I am not exactly sure what you mean, but I think this may help…

if you just want to stop running a certain command after 10,000 frames:

if (frameCount>=10000) {
   exit();
}

if you want to create a new PDF page every 10,000 frames:

if (frameCount % 10000 == 0 && frameCount/10000 != desiredNumPages)
  pdf.nextPage();
} else {
  exit();
}

if neither suggested are what you want, please elaborate on what you want to do

1 Like

Hi, F53.
Thanks a lot for your reply!

Sorry for my poor explanation.


What really I want do is just getting big images for printing posters.
So I need images on PDF or TIFF.

What I am trying way is recording into PDF.

What I do on my scketch is writing balls into a PDF continuasuly until 10,000 ~ 20,000 frame counts.

For example, when 1500 balls are newly added at 1st frame and followd every 1000 frame counts, drawing and recording to PDF always stop at around 3000 frame counts. (The image below shows when they were stopped.)


Now still I can not figure out that this probrem is where come from.
Is it a coding problem?
Is it a problem of PC memory capacity?
Are there any writing restrictions in the PDF specification?


Acturally first of all,
I had tried a way of offscreen buffer (PGraphics) for exporting TIFF.
However I am using objected ArrayList, therefore I could not write like,

ArrayList<Ball> balls;
PGraphics big;

big.balls.blahblah();

Thanks a lot for reading!

It is for sure a memory error, when I ran the script myself it went up to 3000 frames, then gave me an out of memory error.

After increasing processing’s max memory usage to 1000mb, I for some reason got less frames in (~1500)

2 Likes

Thanks for testing the code!

I have changed memmory setting form max memory 4000mb to 8000mb, then tested 1000mb and 512mb.
I tested turning off the check button of max memory as well.

In my enviroment, I did not see OutOfMemmoryError like you.

However, it is still stopped at almost same frame in all memory setting…
wierd something…

As long as seeing your error, it is seems like something is happened around a memmory.
But I dont know why the sketch is always stopped at same frame in any memorry setting in my enviroment…


32

30

15

Have you considered leaving out the screen display while running your sketch? Rendering everything on screen sounds like unnecessary extra steps for your pc, seeing your aim is to get a print-ready pdf. It might improve performance.

2 Likes

Hello, Tiemen.

Thanks for your advice!

I have tested Many Frames Into One PDF File (Without Screen Display). However, exporting is still stopped around 3000 frame count… It is same result as before.

Actually I did not consider to draw to PDF directory without screen display. Because it need to to endRecording manualy when I get nicer generated composition at certain frame count. Actual image I want to print is more complicated artwork with more white space… So I want to stop expoting manualy.

Here is code I have tested, without display screen.

import processing.pdf.*;
ArrayList<Ball> balls = new ArrayList<Ball>();
int ballNum = 1500;
boolean  record;

//-----------------------------------------------
void setup() {
  size(500, 500, PDF, "test.pdf");
  frameRate(120);  

  for (int i = 0; i<ballNum; i++) {
    balls.add(new Ball());
  }
}
//-----------------------------------------------
void draw() {
  for ( Ball b : balls ) {
    b.show();
    b.move();
  }

  if (frameCount%1000 == 0) {
    balls.clear(); 
    for (int i = 0; i<ballNum; i++) {
      balls.add(new Ball());
    }
  }
  println("frameCount /", frameCount);
  
  if (frameCount == 3000) {
    exit();
  } 
}

class Ball {
  PVector pos, vel;
  float r;

  Ball() {
    pos = new PVector(random(width), random(height));
    vel = new PVector(random(-2, 2), random(-2, 2));
    r = random(5, 10);
  }

  void show() {
    noStroke();
    fill(random(255), random(255), random(255), random(255));
    circle(pos.x, pos.y, r);
  }

  void move() {
    pos.x += vel.x;
    pos.y += vel.y;
  }
}

Hi, there.

This issue was solved just now through friend’s reply of my FB post.

The solution was just draw balls only inside of window screen size.

//
// Add if condition inside of show()
if ( pos.x > 0 && pos.x < width && pos.y >0 && pos.y < height ) {
      noStroke();
      fill(random(255), random(255), random(255), random(255));
      circle(pos.x, pos.y, r);
    }

The codes I uploaded did not have any condition to delete balls, when they went out of screen window. After balls went out form window screen, they keeped drawing on outside of window screen. Recording into PDF was stopped due to actual drawn area was uselessly getting bigger too much.

Now I can run skecth through over 20,000 frame counts without stopping to recording into PDF!!!

Here is the latest code.

import processing.pdf.*;
ArrayList<Ball> balls = new ArrayList<Ball>();
int ballNum = 1500;
boolean  record;

//-----------------------------------------------
void setup() {
  size(500, 500);
  frameRate(120);  
  beginRecord(PDF, "test.pdf");

  for (int i = 0; i<ballNum; i++) {
    balls.add(new Ball());
  }
}
//-----------------------------------------------
void draw() {
  for ( Ball b : balls ) {
    b.show();
    b.move();
  }

  if (frameCount%1000 == 0) {
    balls.clear(); 
    for (int i = 0; i<ballNum; i++) {
      balls.add(new Ball());
    }
  }
  println("frameCount /", frameCount);

  if (record == true) { 
    endRecord(); 
    record = false; 
    println("PDF SAVED");
  }
}

class Ball {
  PVector pos, vel;
  float r;

  Ball() {
    pos = new PVector(random(width), random(height));
    vel = new PVector(random(-2, 2), random(-2, 2));
    r = random(5, 10);
  }

  void show() {
    
    // Add this if condition
    if (pos.x >= 0 && pos.x < width && pos.y >= 0 && pos.y < height) {
      noStroke();
      fill(random(255), random(255), random(255), random(255));
      circle(pos.x, pos.y, r);
    }
  }

  void move() {
    pos.x += vel.x;
    pos.y += vel.y;
  }
}

void keyPressed() {
  if (key =='p' || key =='P') record = true;
}

2 Likes

You may want to increase that by the radius of the balls, so that partial balls still exist on the edges of your image.

if ( pos.x > 0-r && pos.x < width+r && pos.y > 0-r && pos.y < height+r ) {
2 Likes

Hi!

Thanks for mention about it!
Yes, it was what I need to do on my code.
Thank you!