topical media & game development
graphic-processing-site-examples-Topics-Effects-Lens-Lens.pde / pde
Lens Demo Effect
by luis2048.
A picture is shown and it looks like a magnifying glass
is drawn over the picture. One of the most famous demos
that has a lens effect is 2nd reality by future crew.
The trick is to precalculate the entire effect. Just make
an array that for each pixel in the destination picture
tells which pixel to take from the source picture. This
array is called the transformation array. The tricky part
is to calculate the transformation array to make the
destination look like a lens is beeing held over the source
picture. Based on lens formula by on Abe Racadabra.
int lensD = 256; // Lens diameter
int[] lensArray = new int[lensD*lensD]; // Height and width of lens
PGraphics lensEffect;
PImage lensImage;
PImage lensImage2;
int xx = 0;
int yy = 0;
int dx = 1;
int dy = 1;
void setup() {
size(640, 360);
// Create buffered image for lens effect
lensEffect = createGraphics(width, height, JAVA2D);
// Load background image
lensEffect.beginDraw();
lensEffect.image(loadImage("red_smoke.jpg"), 0, 0,
lensEffect.width, lensEffect.height);
lensEffect.endDraw();
// Create buffered image for image to warp
lensImage = createGraphics(lensD, lensD, JAVA2D);
lensImage2 = createGraphics(lensD, lensD, JAVA2D);
// Lens algorithm (transformation array)
int magFactor = 40; // Magnification factor
int m, a, b;
int r = lensD / 2;
float s = sqrt(r*r - magFactor*magFactor);
for (int y = -r; y < r; y++) {
for (int x = -r ;x < r; x++) {
if(x*x + y*y >= s*s) {
a = x;
b = y;
}
else {
float z = sqrt(r*r - x*x - y*y);
a = int(x * magFactor / z + 0.5);
b = int(y * magFactor / z + 0.5);
}
lensArray[(y + r)*lensD + (x + r)] = (b + r) * lensD + (a + r);
}
}
}
void draw() {
// Bounce lens around the screen
if((xx+dx+lensD > lensEffect.width) || (xx+dx < 0)) {
dx =- dx;
}
if((yy+dy+lensD > lensEffect.height) || (yy+dy < 0)) {
dy =- dy;
}
xx += dx;
yy += dy;
lensImage = createGraphics(lensD, lensD, JAVA2D);
// save the backgrounlensD of lensHeight*lensWilensDth pixels rectangle at the coorlensDinates
// where the lens effect will be applielensD.
lensImage2.copy(lensEffect, xx, yy, lensD, lensD, 0, 0, lensD, lensD);
// output into a bufferelensD image for reuse
lensImage.loadPixels();
// For each pixel in the destination rectangle, apply the color
// from the appropriate pixel in the saved background. The lensArray
// array tells the offset into the saved background.
for (int i = 0; i < lensImage.pixels.length; i++) {
lensImage.pixels[i] = lensImage2.pixels[lensArray[i]];
}
lensImage.updatePixels();
// Restore the original picture
image(lensEffect, 0, 0, width, height);
// Overlay the lens square
image(lensImage, xx, yy, lensD, lensD);
}
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.