Saving & Exporting
Save frames as images, export animation sequences for video, build standalone applications, generate PDFs, and share your work on OpenProcessing.
Saving a Single Frame
The simplest form of output: save the current state of the canvas as an image.
save("my-sketch.png");
Call save() anywhere in your sketch — inside draw(), inside a key event, wherever makes sense. The image is saved in the sketch’s folder (the same folder as your .pde file). Supported formats are PNG, JPEG, TGA, and TIFF.
To save on demand when a key is pressed:
void keyPressed() {
if (key == 's' || key == 'S') {
save("snapshot.png");
println("Saved snapshot.png");
}
}
PNG is the best default — it’s lossless, supports transparency, and is universally readable. Use JPEG only if file size is a concern and you can tolerate lossy compression.
saveFrame() — Numbered Sequential Frames
saveFrame() is save()’s more powerful sibling. It saves the current frame with an auto-incrementing number, making it ideal for capturing animation:
void draw() {
// ... your drawing code ...
saveFrame("output/frame-####.png");
}
The #### in the filename is replaced with the frame number, zero-padded to four digits: frame-0001.png, frame-0002.png, and so on.
The output/ prefix saves into a subfolder of the sketch folder. Processing creates the folder automatically if it doesn’t exist.
Important: saveFrame() inside draw() saves every single frame, which can be thousands of files very quickly and slow the sketch down considerably. Use it only when you intend to capture the full animation, and add a stop condition:
int totalFrames = 300; // capture 5 seconds at 60fps
void setup() {
size(800, 600);
frameRate(60);
}
void draw() {
// ... drawing code ...
saveFrame("output/frame-####.png");
if (frameCount >= totalFrames) {
println("Done capturing " + totalFrames + " frames.");
exit();
}
}
This sketch captures exactly 300 frames and then quits cleanly.
Converting Frames to Video with ffmpeg
Once you have a sequence of numbered PNG files, you can stitch them into a video using ffmpeg — a free, open-source command-line tool available at ffmpeg.org.
Navigate to the sketch’s output/ folder in your terminal, then run:
ffmpeg -framerate 60 -i frame-%04d.png -c:v libx264 -pix_fmt yuv420p output.mp4
Breaking down the arguments:
| Argument | Meaning |
|---|---|
-framerate 60 |
Input frame rate — match what you used in Processing |
-i frame-%04d.png |
Input pattern — %04d matches 4-digit numbers |
-c:v libx264 |
Encode as H.264 video (widely compatible) |
-pix_fmt yuv420p |
Color format compatible with most players and social media |
output.mp4 |
Output filename |
For a transparent-background video (e.g., for compositing):
ffmpeg -framerate 60 -i frame-%04d.png -c:v libvpx-vp9 -pix_fmt yuva420p output.webm
For a GIF (best for short loops under ~5 seconds):
ffmpeg -framerate 30 -i frame-%04d.png -vf "fps=30,scale=800:-1:flags=lanczos" output.gif
Export Application: Standalone Desktop App
Processing can package your sketch as a standalone application that runs without Processing installed. Go to File > Export Application (or press Ctrl/Cmd+Shift+E).
The export dialog asks:
- Platform: Windows, macOS, Linux — you can export for all three simultaneously
- Full screen on start: Enable this for installations
- Stop button: Whether to show a stop button in the application window
- Embed Java: Always leave this checked — it bundles the Java runtime with your app so it runs on machines without Java installed
After export, Processing creates a folder inside your sketch folder:
my_sketch/
├── my_sketch.pde
└── application.windows64/
├── my_sketch.exe
├── my_sketch.bat
├── lib/
└── java/
On macOS, you get a .app bundle. On Linux, a shell script. These can be distributed to anyone and run without any additional software.
Notes on Export Application:
- The sketch window size is fixed to what you set in
size()— users can’t resize it unless you handle that in code - File access paths work relative to where the
.exe/.applives, which may differ from development. UsesketchPath("")to get the absolute path to the sketch directory at runtime fullScreen()insetup()combined with the “full screen on start” export option is the standard approach for gallery installations
PDF Export
The PDF library (bundled with Processing) lets you save your sketch output as a scalable PDF. This is invaluable for print work — a PDF can be sent to a print shop and reproduced at any size without pixelation.
First, import the PDF library at the top of your sketch:
import processing.pdf.*;
Then use it in one of two ways:
Single-Frame PDF
Wrap your drawing code between beginRecord() and endRecord():
import processing.pdf.*;
void setup() {
size(800, 800);
beginRecord(PDF, "output.pdf");
}
void draw() {
background(255);
// Your drawing code here
fill(50, 100, 200);
noStroke();
for (int i = 0; i < 20; i++) {
float x = random(width);
float y = random(height);
float d = random(20, 100);
ellipse(x, y, d, d);
}
endRecord();
exit(); // quit after saving
}
On-Demand PDF Save
A more flexible approach: save to PDF when a key is pressed, while the sketch continues running:
import processing.pdf.*;
boolean savePDF = false;
void draw() {
if (savePDF) {
beginRecord(PDF, "output-####.pdf"); // #### = frameCount
}
background(255);
// ... your drawing code ...
if (savePDF) {
endRecord();
savePDF = false;
println("PDF saved.");
}
}
void keyPressed() {
if (key == 'p' || key == 'P') savePDF = true;
}
Press P to capture the current frame as a PDF. The #### in the filename auto-increments so you can save multiple PDFs without overwriting.
Note: The PDF library captures vector output from Processing’s drawing functions. Pixel-level operations (like loadPixels() or set()) do not translate to vector PDF — only the standard drawing functions do.
Sharing on OpenProcessing
OpenProcessing.org is the main social platform for Processing and p5.js sketches. It lets you publish, share, and run sketches directly in the browser.
To share a Processing sketch:
- Create a free account at openprocessing.org
- Click Create Sketch
- Paste your Processing code into the editor
- The platform runs it using a Processing-compatible renderer (some advanced features may not work)
- Set a title, description, and tags
- Click Publish
Your sketch gets a unique URL you can share anywhere. Other users can fork it, remix it, and comment on it.
OpenProcessing is also an excellent way to discover techniques — browse the “Popular” and “Trending” sections for inspiration, then click “Code” on any sketch to read the source.
Processing.js and p5.js Conversion (Legacy Context)
Older resources mention Processing.js — a JavaScript library that translated Processing code to run in the browser. Processing.js is no longer actively maintained and has significant compatibility gaps. Ignore it for new projects.
For web embedding, the modern path is to rewrite the sketch in p5.js. Because p5.js closely mirrors the Processing API, most sketches require only minor changes:
| Processing | p5.js |
|---|---|
void setup() |
function setup() |
void draw() |
function draw() |
float x = 0; |
let x = 0; |
color c = color(...) |
let c = color(...) |
println() |
console.log() |
ArrayList<T> |
Standard JS arrays |
Most drawing functions (ellipse, rect, fill, stroke, etc.) are identical in p5.js. The main differences arise from Java vs JavaScript type systems and Java-specific libraries.
A Complete Capture-to-Video Workflow
Putting it all together: here’s the workflow for creating a polished video from a Processing animation.
Step 1: Design your sketch. Use frameRate(60) in setup.
Step 2: Add frame capture with a limited frame count:
void setup() {
size(1080, 1080); // 1:1 aspect ratio, common for social media
frameRate(60);
}
void draw() {
// ... your animation ...
if (frameCount <= 360) { // 6 seconds at 60fps
saveFrame("output/frame-####.png");
} else {
noLoop(); // stop draw() loop when done
println("Capture complete. " + frameCount + " frames saved.");
}
}
Step 3: Run the sketch. Wait for it to finish saving frames.
Step 4: In a terminal, navigate to the sketch’s output/ folder and run:
ffmpeg -framerate 60 -i frame-%04d.png -c:v libx264 -pix_fmt yuv420p -crf 18 animation.mp4
The -crf 18 flag sets quality — lower numbers mean higher quality. 18 is visually near-lossless.
Step 5: Review the video in a player. If the animation is meant to loop, confirm the last frame transitions cleanly back to the first.
What’s Next
You’ve now covered the full starter foundation of Processing: the coordinate system, drawing primitives, color, variables, animation, mouse and keyboard interaction, and output. From here, the natural directions are:
- Noise and randomness — Perlin noise (
noise()) for organic, natural-looking variation - Object-oriented design — using Java classes to manage many independent moving entities
- Data and arrays — loading data files and visualizing them
- Images and pixels — loading images, reading and writing pixel values
- Libraries — adding sound, video, physical computing, and 3D rendering
The OpenProcessing community, Daniel Shiffman’s Coding Train, and the official Processing reference at processing.org/reference are the best places to continue from here. Keep a sketch open and keep experimenting.