Created
December 5, 2012 15:02
-
-
Save andreasf/4216201 to your computer and use it in GitHub Desktop.
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
class KenBurnsImage { | |
final float AMOUNT_ZOOM = 0.05; // per second | |
final float AMOUNT_PAN = width / 64f; // per second | |
final float OVERSCALE = 1.2; | |
PImage img; | |
int fadeInTime; | |
int created = -1; | |
float dispWidth = 0.0; | |
float dispHeight = 0.0; | |
float dispX = 0; | |
float dispY = 0; | |
float dispScale = 0.0; | |
final float amountPanX; | |
final float amountPanY; | |
final boolean zoomIn; | |
final int lifetime; | |
KenBurnsImage(String filename, int fadeInTime, int lifetime, boolean zoomIn) { | |
img = loadImage(filename); | |
scaleAndPosition(); | |
// set pan direction | |
float direction = random(TWO_PI); | |
amountPanX = AMOUNT_PAN * cos(direction); | |
amountPanY = AMOUNT_PAN * sin(direction); | |
this.fadeInTime = fadeInTime; | |
this.zoomIn = zoomIn; | |
this.lifetime = lifetime; | |
} | |
void reset() { | |
scaleAndPosition(); | |
created = -1; | |
} | |
void scaleAndPosition() { | |
float wWidth = (float)width * OVERSCALE; | |
float wHeight = (float)height * OVERSCALE; | |
float scaleX = wWidth / (float)img.width; | |
float scaleY = wHeight / (float)img.height; | |
float scale = Math.min(scaleX, scaleY); | |
dispWidth = (float)img.width * scale; | |
dispHeight = (float)img.height * scale; | |
// position | |
dispY = (wHeight - dispHeight) / 2f; | |
dispX = (wWidth - dispWidth) / 2f; | |
} | |
void draw() { | |
if (created == -1) { | |
created = millis(); | |
} | |
int alive = millis() - created; | |
float progress = (float)alive / 1000f; | |
if (!this.zoomIn) { | |
progress = (float)lifetime / 1000f - progress; | |
progress = max(0.0, progress); | |
} | |
dispScale = progress * AMOUNT_ZOOM; | |
float nWidth = dispScale * dispWidth; | |
float nHeight = dispScale * dispHeight; | |
float dWidth = dispWidth + nWidth; | |
float dHeight = dispHeight + nHeight; | |
float xOffset = nWidth / -2.0; | |
float yOffset = nHeight / -2.0; | |
xOffset += progress * amountPanX; | |
yOffset += progress * amountPanY; | |
float tProgress = 1.0; | |
if (alive < fadeInTime) { | |
tProgress = (float)alive / (float)fadeInTime; | |
tProgress = min(1.0, tProgress); | |
tint(255, tProgress*255f); | |
} | |
fill(0, 0, 0, tProgress*255f); | |
rect(0, 0, width, height); | |
pushMatrix(); | |
scale(dispScale + 1.0); | |
translate(xOffset, yOffset); | |
image(img, dispX, dispY, dispWidth, dispHeight); | |
popMatrix(); | |
noTint(); | |
} | |
} |
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
import processing.video.*; | |
final int appletWidth = 1024; | |
final int appletHeight = 768; | |
final int IMG_DURATION = 7000; | |
final int FADE_DURATION = 3000; | |
final int REMOVE_AFTER = 100; | |
String[] images = {"eins.jpg", "vier.png", "zwei.jpg", "drei.jpg"}; | |
KenBurnsImage[] imgs; | |
KenBurnsImage current; | |
KenBurnsImage next; | |
KenBurnsImage previous; | |
int imageOffset = 0; | |
int lastFrame = 0; | |
boolean zoomIn = true; | |
void setup() { | |
size(1024, 768, P2D); | |
println("loading "+images.length+" images..."); | |
imgs = new KenBurnsImage[images.length]; | |
for (int i=0; i<images.length; i++) { | |
imgs[i] = new KenBurnsImage(images[i], FADE_DURATION, | |
IMG_DURATION + FADE_DURATION, zoomIn); | |
} | |
current = getNextImage(); | |
next = getNextImage(); | |
} | |
KenBurnsImage getNextImage() { | |
KenBurnsImage i = imgs[imageOffset]; | |
imageOffset = (imageOffset + 1) % imgs.length; | |
return i; | |
} | |
void movieEvent(Movie m) { | |
m.read(); | |
} | |
void draw() { | |
int alive = millis(); | |
int frameOffset = alive % IMG_DURATION; | |
if (frameOffset < lastFrame) { | |
previous = current; | |
current = next; | |
} | |
background(0); | |
if (previous != null) { | |
if (frameOffset > FADE_DURATION + REMOVE_AFTER) { | |
previous = null; | |
next = getNextImage(); | |
next.reset(); | |
} else { | |
previous.draw(); | |
} | |
} | |
current.draw(); | |
saveFrame("frames/####.tif"); | |
lastFrame = frameOffset; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment