Time based decay, aka pixelation

For this week’s ICM assignment, I wanted to pixelate an image based on time. The idea was that it would take three days to pixelate the entire image into a solid color. Below are sample interactions based on a much shorter time period.

Click to start or pause.

pause from Jiashan Wu on Vimeo.

Press b/B to rewind and f/F to continue.

back from Jiashan Wu on Vimeo.

float v = 1.0 / 4.0;
float[][] kernel = {
{
v, v
}
, {
v, v,
}
};
PImage mypic;
int lasttime;
int count;
int totalsteps;
int direction;
int increment;
boolean paused;
void setup() {
//size(800,600);
mypic = loadImage("http://www.popportraits.com/paintings/Max/Max-MondrianLady.jpg");
size(mypic.width, mypic.height);
lasttime = 0;
count = 1;
increment = 5;
direction = 1;
paused = true;
totalsteps = mypic.width;
image(mypic, 0, 0); // Displays the image from point (0,0)
}
void draw() {
//image(mypic, 0, 0); // Displays the image from point (0,0)
mypic.loadPixels();
if (paused == false) {
if (millis() - lasttime >= 100) {
if (count >= 1 && count <= mypic.width) {
pixelate(count);
count += increment * direction;
if (count < 1) count = 1;
if (count > mypic.width) count = mypic.width;
}
lasttime = millis();
}
}
if(keyPressed){
if (key == 'b' || key == 'B') direction = -1;
else if (key == 'f' || key == 'F') direction = 1;
}
timer();
}
void pixelate(int a) {
// Loop through every pixel in the image
for (int y = 1; y < mypic.height-1; y += a) { // Skip top and bottom edges
for (int x = 1; x < mypic.width-1; x += a) { // Skip left and right edges
float sum_r = 0; // Kernel sum for this pixel
float sum_g = 0; // Kernel sum for this pixel
float sum_b = 0; // Kernel sum for this pixel
for (int ky = -1; ky <= 0; ky++) {
for (int kx = -1; kx <= 0; kx++) {
// Calculate the adjacent pixel for this kernel point
int placeInBigArray = (y + ky)*mypic.width + (x + kx);
float val_r = red(mypic.pixels[placeInBigArray]);
float val_g = green(mypic.pixels[placeInBigArray]);
float val_b = blue(mypic.pixels[placeInBigArray]);
// Multiply adjacent pixels based on the kernel values
sum_r += kernel[ky+1][kx+1] * val_r;
sum_g += kernel[ky+1][kx+1] * val_g;
sum_b += kernel[ky+1][kx+1] * val_b;
}
}
//draw new pixels
fill(sum_r, sum_g, sum_b);
noStroke();
rect(x-1, y-1, a, a);
}
}
}
void timer() {
fill(0);
noStroke();
ellipse(mypic.width/2, mypic.height/2, 100, 100);
fill(255);
float pct = float(count)/float(totalsteps);
arc(mypic.width/2, mypic.height/2, 100, 100, 0-HALF_PI, radians(360 * pct)-HALF_PI, PIE);
}
void mousePressed() {
paused = !paused;
}