Skip to content

Instantly share code, notes, and snippets.

@andreasf
Created December 5, 2012 15:02
Show Gist options
  • Save andreasf/4216201 to your computer and use it in GitHub Desktop.
Save andreasf/4216201 to your computer and use it in GitHub Desktop.
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();
}
}
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