////////////////////////////////////////////////////////////////
///////// i n t e r ///////////////////////////////////////////
//////////////////////////////////////////// l a c e d /////////
////////////////////////////////////////////////////////////////
///////// (c) martin schneider 2010 ////////////////////////////
////////////////////////////////////////////////////////////////
// inspired by the work of J.K. Keller:
// http://www.jk-keller.com/works/2009/reverse-keetra
// input
PImage img;
int[][] edges;
int minborder = -2;
// transform params
float t1, t2;
int jerk = 2;
int raster = 2;
int mirror = -1;
int b = minborder;
int fc;
////////////////////////////////////////////////////////////////
void setup() {
// Image by Ashley R. Good ( http://www.flickr.com/photos/kmndr/2788742255/ ) CC-by-2.0
img = loadImage("profile.jpg");
edges = edges(img, 8, 6);
//img = loadImage("http://www.jk-keller.com/works/images/you-me-you-kd-orig-470.jpg");
//edges = edges(img, 8, 6);
//img = loadImage(http://www.jk-keller.com/works/images/you-me-you-jk-orig-470.jpg");
//edges = edges(img, 12, 6);
size(img.width, img.height);
}
////////////////////////////////////////////////////////////////
void draw() {
tint(255, 64);
int frames = frameCount - fc;
int tx = frames % raster - raster/2;
int ty = (frames / raster) % raster;
image(interlace(img), tx*jerk, ty*jerk);
}
////////////////////////////////////////////////////////////////
void keyPressed() {
switch(key) {
case 'j': jerk=jerk^10; raster=raster^10; fc = frameCount; break;
case 'm': mirror *= -1; break;
}
}
////////////////////////////////////////////////////////////////
///////// interlace transform //////////////////////////////////
////////////////////////////////////////////////////////////////
PImage interlace(PImage img) {
// t1 --- horizontal distance from the center
t1 += (mouseX - width/2) / 8;
// t2 lags behind
t2 = lerp(t2, t1, .1);
// border --- vertical distance from the center
b = (int) max(minborder, height/2 - 1.2*abs(mouseY-height/2));
// copy the image
PImage pic = img.get();
// transform every single rasterline
for(int y=0; y<height; y++) {
// raster line offset by t1 and t2, possibly with mirror effect
float tx = y % 2 > 0 ? mirror * t1 : t2;
// left and right edges
int on = edges[0][y], off = edges[1][y];
if(on>0 && off<width-1) { // igonore abberations
// add some border to the raster lines
on = max(0, on-b);
off = min(width-1, off+b);
int d = off-on;
// the actual raster line transform
for(int x=0; x<d; x++)
pic.set(on+x, y, img.get(on + abs(int( x + tx * float(d) / width )) % d, y));
}
}
return pic;
}
////////////////////////////////////////////////////////////////
//////////////////// left and right edges of a profile /////////
////////////////////////////////////////////////////////////////
int[][] edges(PImage img, int treshold, int smoothen) {
// arrays for left and right edge positions
int h = img.height;
int w = img.width;
int[][] edges = new int[2][h];
for(int y=0; y<h; y++) {
// get brightness values for a single raster line
int bright[] = new int[w];
for(int x=0; x<w; x++)
bright[x] = (int) brightness(img.get(x,y));
// detect left edge
for(int x=w-6; x>0; x--)
if(abs(bright[x] - bright[x+1]) > treshold)
edges[0][y] = x;
// detect right edge
for(int x=5; x<w-1; x++)
if(abs(bright[x] - bright[x-1]) > treshold)
edges[1][y] = x;
}
// smoothen edges
edges[0] = smoothen(edges[0], smoothen);
edges[1] = smoothen(edges[1], smoothen);
return edges;
}
////////////////////////////////////////////////////////////////
///////// smoothen a sequence of values ////////////////////////
////////////////////////////////////////////////////////////////
int[] smoothen(int[] a, int range) {
int[] a2 = new int[a.length];
int dleft = range/2;
int dright = range - dleft;
int l = a.length - 1;
for(int i=0; i<l; i++) {
// actual range limits
int jmin = max(0, i - dleft);
int jmax = min(l, i + dright);
// calculate mean value
for(int j=jmin; j<jmax; j++) {
a2[i] += a[j];
}
a2[i]/=(jmax-jmin);
}
return a2;
}
Use your mouse to explore interlace space.
[m] mirror on/off
[j] jerk on/pff
Inspired by the work of JK Keller
http://www.jk-keller.com/works/2009/reverse-keetra
Source image by Ashley R. Good (CC-BY-2.0)
http://www.flickr.com/photos/kmndr/2788742255/