/** Channel Adjust Dave Bollinger, Dec 2006 http://www.davebollinger.com for Processing 0123 Beta Drag sliders to adjust scaling factor and offset of each channel Formula is same as used by Flash's "Advanced" blend mode: RGB' = RGB * X + Y (essentially a per-channel contrast and brightness adjustment) */ PImage src, dst; int [] values; HScrollbar [] bars; int [] rtable, gtable, btable; static int RX=0, RY=1, GX=2, GY=3, BX=4, BY=5; static String [] labels = { "Red X", "Red Y", "Green X", "Green Y", "Blue X", "Blue Y" }; void setup() { size(200,200,P3D); src = loadImage("eames.jpg"); dst = src.get(); PFont font = loadFont("small-6.vlw"); bars = new HScrollbar[6]; values = new int[6]; for (int i=0; i<6; i++) { bars[i] = new HScrollbar(10+(i&1)*100, height-50+(i/2)*15, 80, 8, 5, labels[i], font); bars[i].setRange(0,255); values[i] = ((i&1)==0) ? 255 : 0; bars[i].setValue((float)(values[i])); } rtable = new int[256]; gtable = new int[256]; btable = new int[256]; } void draw() { boolean changed = false; for (int i=0; i<6; i++) { bars[i].update(); if (bars[i].getValue() != values[i]) { values[i] = bars[i].getValue(); changed = true; } } if (changed) { channelAdjustImage(src,dst,values); } background(dst); for (int i=0; i<6; i++) bars[i].draw(); } int peg(int n) { return (n < 0) ? 0 : ((n > 255) ? 255 : n); } void channelAdjustImage(PImage src, PImage dst, int [] values) { for (int i=0; i<256; i++) { rtable[i] = peg(((i * values[RX]) >> 8) + values[RY]); gtable[i] = peg(((i * values[GX]) >> 8) + values[GY]); btable[i] = peg(((i * values[BX]) >> 8) + values[BY]); } int [] sp = src.pixels, dp = dst.pixels; for (int i=dp.length-1; i>=0; i--) { int c = sp[i]; dp[i] = (c & 0xFF000000) | (rtable[(c&0xFF0000)>>16]<<16) | (gtable[(c&0xFF00)>>8]<<8) | (btable[(c&0xFF)]) ; } }