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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |