I’m heading to the beach on Monday, which means that the beard had to go. I don’t know when it might return — certainly not for a long time. It was fun, but I think I’m probably just not cut out to operate a beard at a professional level. Ah well.
Of course, there was still the question of how to shave it off. Usually this is taken as an opportunity to briefly sport some funny or Wolverine-related facial hair configurations, but I decided I’d waste even more time and nerd it up a bit.
I adapted one of the demo sketches that ships with Processing to facilitate lining the shots up; if you want to do something similarly dumb, you can find the code after the jump (you’ll need to update the system path near the bottom).
I encourage those of you with access to small, gullible children to tell them that the above gif represents how beards actually grow in.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
/* a tool for creating an animated gif of yourself doing something dumb based heavily on the background diff example that ships with processing displays diffs between frames over a threshold so that you can see where you've moved hit spacebar to take a snapshot all frames from a given run will have the same timestamp prefix, e.g. frame-1300552348-#.png can then convert to an animated gif using eg http://www.lcdf.org/gifsicle/ or (w/ imagemagick) "convert -delay 13 -loop 0 *.png output.gif" */ import processing.video.*; int numPixels; int[] backgroundPixels; Capture video; long startTime = 0; int counter = 0; void setup() { // Change size to 320 x 240 if too slow at 640 x 480 size(640, 480, P2D); video = new Capture(this, width, height, 24); numPixels = video.width * video.height; // Create array to store the background image backgroundPixels = new int[numPixels]; // Make the pixels[] array available for direct manipulation loadPixels(); Date d = new Date(); startTime=d.getTime()/1000; } void draw() { if (video.available()) { video.read(); // Read a new video frame video.loadPixels(); // Make the pixels of video available // Difference between the current frame and the stored background int presenceSum = 0; for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame... // flip the display horizontally -- makes it mirrorlike; easier to line yourself up with it int j = (i - (i%width)) + ((width-1) - (i%width)); // Fetch the current color in that location, and also the color // of the background in that spot color currColor = video.pixels[j]; color bkgdColor = backgroundPixels[j]; // Extract the red, green, and blue components of the current pixel’s color int currR = (currColor >> 16) & 0xFF; int currG = (currColor >> 8) & 0xFF; int currB = currColor & 0xFF; // Extract the red, green, and blue components of the background pixel’s color int bkgdR = (bkgdColor >> 16) & 0xFF; int bkgdG = (bkgdColor >> 8) & 0xFF; int bkgdB = bkgdColor & 0xFF; // Compute the difference of the red, green, and blue values int diffR = abs(currR - bkgdR); int diffG = abs(currG - bkgdG); int diffB = abs(currB - bkgdB); // provide a "ghost" image to help line things up float c = 0.5; int newR = round((c*currR) + ((1-c)*bkgdR)); int newG = round((c*currG) + ((1-c)*bkgdG)); int newB = round((c*currB) + ((1-c)*bkgdB)); float totalDiff = (diffR+diffG+diffB) / (255.0*3); if (totalDiff>0.3) pixels[i] = 0xFFFF0000; else pixels[i] = 0xFF000000 | (newR<<16) | (newG<<8) | newB; } updatePixels(); // Notify that the pixels[] array has changed } } // When a key is pressed, capture the background image into the backgroundPixels // buffer, by copying each of the current frame’s pixels into it. void keyPressed() { video.loadPixels(); arraycopy(video.pixels, backgroundPixels); PImage temp = createImage(width, height, RGB); temp.loadPixels(); arraycopy(video.pixels, temp.pixels); temp.updatePixels(); temp.save("/path-to-output-directory/frame-" + startTime + "-" + counter + ".png"); counter = counter + 1; } |
My favorite part is the boogie you’re doing, even if it’s an artifact.
Marie says, “he sort of looks like an alien”.
I agree with both of you. But yes, the boogying is a problem. It was even worse in the original version, before I cropped it more tightly.
There’s a certain yearning that comes through the canvas.