/**
Adjust scrollbars to reprocess image.
Click buttons to select new source image.
Right-click mouse to display original image for comparison.
Ortonizer
Dave Bollinger, Feb 2006
http://www.davebollinger.com
For Processing 0109 Beta
(recompiled with 0124 while contemplating 0125 blend modes, Jan 2007)
An implementation of a technique named after photographer Michael Orton.
For example see the Orton Pool on Flickr.
An image is brightened, then blurred then blended with itself
to achieve a soft diffusion highlight, almost an airbrushed effect.
(Orton's original technique involved overlaying two separate negatives that
were overexposed by controlled amounts, one sharp focused, one soft focused.)
*/
PImage source, ortonized;
void setup() {
size(400, 340);
UIInit();
}
void draw() {
UIUpdate();
image((mousePressed && mouseButton==RIGHT) ? source : ortonized, 0, 0);
UIDraw();
}
//===========================
// IMAGE PROCESSING ROUTINES
//===========================
PImage Ortonize(PImage img, int briteness, float blurradius) {
// a screen overlay is also commonly used, though i think plain old brightness more often looks better
PImage brightened = Brightness(img, briteness);
PImage blurred = Blur(brightened, blurradius);
return Multiply(brightened, blurred);
}
int peg(int n) {
return (n < 0) ? 0 : ((n > 255) ? 255 : n);
}
// TODO: use ImageAdjuster lib or 0125's screen blend mode
PImage Brightness(PImage imgA, int amount) {
PImage imgC = new PImage(imgA.width, imgA.height);
int [] pixA = imgA.pixels;
int [] pixC = imgC.pixels;
int n = imgA.width * imgA.height;
for (int i=0; i> 16) + amount;
int gg = ((a & GREEN_MASK) >> 8) + amount;
int bb = ((a & BLUE_MASK)) + amount;
pixC[i] = 0xFF000000 | (peg(rr)<<16) | (peg(gg)<<8) | (peg(bb));
}
return imgC;
}
PImage Blur(PImage in, float radius) {
PImage out = in.get();
out.filter(BLUR, radius);
return out;
}
// TODO: use 0125's multiply blend mode
PImage Multiply(PImage imgA, PImage imgB) {
PImage imgC = new PImage(imgA.width, imgA.height);
int [] pixA = imgA.pixels;
int [] pixB = imgB.pixels;
int [] pixC = imgC.pixels;
int n = imgA.width * imgA.height;
for (int i=0; i> 16) * ((b & RED_MASK) >> 16)) >> 8;
int gg = (((a & GREEN_MASK) >> 8) * ((b & GREEN_MASK) >> 8)) >> 8;
int bb = (((a & BLUE_MASK)) * ((b & BLUE_MASK))) >> 8;
pixC[i] = 0xFF000000 | (peg(rr)<<16) | (peg(gg)<<8) | (peg(bb));
}
return imgC;
}