Golan Levin and Collaborators

Flong Blog + News

Three Tiny Programs: Time-Lapse, Stop-Motion, Slit-Scan

4 January 2009 / code, pedagogy, reference

This afternoon, I created three tiny Processing programs to serve as educational tools for exploring different relationships between video and time: time-lapse recording, stop-motion animation, and slit-scan imaging. These programs were created for students in my new course, “Interactive Technologies for Live Performance”, which I’m teaching this spring in collaboration with Matt Gray from the CMU School of Drama.

A Time-Lapse Recorder

This Processing program for Time-Lapse Recording connects to the computer’s built-in web camera (or other attached video camera), and then stashes images from the camera to the hard disk at regular intervals. To use this program, download the free Processing environment, copy-and-paste the following text into the main Processing code area, save the sketch, and press the Run button. (The program will start recording consecutively-numbered images into the Sketch Folder for that program, which you can access from the Sketch menu. To compile a video from these images, import them into your favorite video editor, such as Quicktime Pro, AfterEffects or FinalCut).

// TINY TIME-LAPSE PROGRAM
// Saves an image from the camera once per second,
// or at some other user-defined interval.
// For Processing Version 1.01.

//----------------------------------------------------------
// Parameters you can modify
int videoWidth  = 320; // could be 160, 320, 640, etc.
int videoHeight = 240; // could be 120, 240, 480, etc.
int     period = 1000; // milliseconds between frames

//----------------------------------------------------------
import  processing.video.*;
Capture myCapture;
long    lastCaptureTime = 0;
int     saveCount = 0;

//----------------------------------------------------------
void setup(){
  myCapture = new Capture(this, videoWidth,videoHeight);
  size(myCapture.width,myCapture.height);
}

//----------------------------------------------------------
void draw() {
  if(myCapture.available()) {
    myCapture.read();
    image(myCapture, 0,0); 

    long now = millis();
    if ((now - lastCaptureTime) >= period){
      String filename = "timelapse_" + nf(saveCount, 6) + ".jpg";
      saveFrame(filename);
      lastCaptureTime = now;
      saveCount++;
    }
  }
}

A Stop-Frame Animation Tool

The following code for a Stop-Frame Animation tool is very similar, but it only records images to disk when the user clicks the mouse or presses a key on the keyboard. It also includes a very basic “onion-skinning” feature, which allows you to see the current video signal in relation to the previously captured image.

// TINY STOP-FRAME PROGRAM
// Saves an image from the camera when a key/mouse is pressed.
// For Processing Version 1.01.

//----------------------------------------------------------
// Parameters you can modify:
int videoWidth  = 320; // could be 160, 320, 640, etc.
int videoHeight = 240; // could be 120, 240, 480, etc.
int onionSkinTransparency = 127; // between 0 and 255

//----------------------------------------------------------
import  processing.video.*;
PImage  previousImage;
Capture myCapture;
int     saveCount = 0;
boolean bDoSave = false;

//----------------------------------------------------------
void setup(){
  myCapture = new Capture(this, videoWidth,videoHeight);
  size(myCapture.width,myCapture.height);
  previousImage = new PImage(myCapture.width,myCapture.height);
}

//----------------------------------------------------------
void keyPressed(){
  bDoSave = true;
}
void mousePressed(){
  bDoSave = true;
}

//----------------------------------------------------------
void draw() {
  if(myCapture.available()) {
    myCapture.read();

    if (bDoSave){
      noTint();
      image(myCapture, 0,0); 

      String filename = "stopframe_" + nf(saveCount++, 5) + ".jpg";
      saveFrame(filename);
      bDoSave = false;

      previousImage.loadPixels();
      arrayCopy (myCapture.pixels, previousImage.pixels);
      previousImage.updatePixels();
    }
    else {
      noTint();
      image(previousImage, 0,0);
      tint(255, 255, 255, onionSkinTransparency);
      image(myCapture, 0,0);
    }
  }
}

An Interactive Slit-Scan Imager

Slit-Scan imaging techniques are used to create static images of time-based phenomena. In the digital realm, thin slices of pixels are extracted from a sequence of video frames, and concatenated into a new image. I’ve been compiling an informal catalog of slit-scan video artworks for a few years; as programming environments for the arts have evolved, it has become easier and easier to experiment with slit-scan techniques. With the recent release of Processing 1.0, I thought I would try my hand at writing the shortest real-time slitscanning program ever:

// For Processing Version 1.01.
import processing.video.*;
Capture myCapture;
int X=0;
void setup(){
  myCapture = new Capture (this, 320,240);
  size(600,240);
}
void draw() {
  if (myCapture.available()) {
    myCapture.read();
    copy(myCapture, (myCapture.width/2),0,1,myCapture.height, (X++%width),0,1,height);
  }
}

Comments are closed.

« Prev post:
» Next post: