25 Jan 2013

I went with the threshold method. Ideally, I think it should use background subtraction, but thats for another day.
The rainbow circles give the letters legibility, playfulness, and greater visual weight. I encountered several challenges with this project.
It took me about 4 hours.
I commented the heck out of my mediocre code if anyone is curious.
I have trouble with logic, so that section is likely verbose and roundabout. I’d love some tips.

GitHub Link

////RobbRain/////Textrain Spinoff, after Camille Utterback

import*; ///add the library

Capture video;

int threshold = 122; //brightness value to count as dark
int letterSize = 20; //diameter of circles, real or imaginary that bound the falling shapes
int columnWidth = 20; //how wide you want the columns to be
int columnQty; //dependent on above
int numPix; //dependent, how many pixels are there?
int[] fallingY; //array of all the y values of our objects
String poem = "Trust not he who winces in rain.";

//char[] poem = { o,h, };  // Alternate syntax

void setup() {
  size(640, 480, P2D); // Change size to 320 x 240 if too slow at 640 x 480
  video = new Capture(this, width, height);
  colorMode(HSB); //easy rainbows man
  noCursor(); //cursors are for sissys
  noStroke();//as are strokes
  smooth();//doesn't work.
  numPix = video.width*video.height; //calc the pixel qty
  columnQty = width/columnWidth; //calc the column qty

  fallingY = new int[columnQty]; //size that array
  for (int i = 0; i height||fallingY[i]<0) {//if it falls off the bottom or top, it should go again. no giving up
        fallingY[i] = 10;
      fallingLetter(sampleX, fallingY[i], poem.charAt(i),i); ///draws the thing.
    if(mousePressed){setup();}////cute.. puts the letters at top if click.

void fallingLetter(int letterX, int letterY, char letter, int i) {
  fill(map(i, 0, columnQty, 0, 255), 255, 255, 100);
  ellipse(letterX, letterY, letterSize, letterSize);
  text(letter, letterX-letterSize/3, letterY+letterSize/5);

int brightnessXY(int xxx, int yyy) { ///this lil guy calc the brightness of a video pixel and returns it as an int.
  int  videoIndex = constrain(yyy * video.width + xxx, 0, numPix-1);   //index = y*videoWidth + x
  int briteSpot = int(brightness(video.pixels[videoIndex]));
  return briteSpot;

void mouseTrack() { //useful for finding the proper threshold.
  float briteMouse = brightnessXY(mouseX, mouseY);
  if (briteMouse > threshold) { 
  else { 
  rect(mouseX, mouseY, 20, 20);