fullscreen
controller.pdegui.pdeimageMasher.pdeliveImageMasher.pdeslider.pdetheEngine.pde
class Controller {
color bckCol = color(#1a1a1a);
color overCol = color(#FFCC22);
color normCol = color(#B9B9B9);
int id;
ArrayList sliders;
PVector pos;
boolean ready = false;
GUI parent;
TheEngine engine;
PGraphics rohy[];
PGraphics roh;
ArrayList ctlFields;
float percent = 0;
int w = 127;
int cx = -10;
int cy = -10;
int wx = 85;
String name;
Object unit;
Class<?> myClass;
Field[] fields;
Controller(GUI _parent, int _id) {
parent = _parent;
engine = parent.parent;
harvestFields();
// randomize default vaues for each picture
for(int i =0 ; i < parent.defaults.length;i++)
if(!parent.DEFAULT_NAMES[i].equals("x")||!parent.DEFAULT_NAMES[i].equals("y"))
parent.defaults[i] *= random(.7,1.);
id = _id;
roh = createGraphics(8,8,JAVA2D);
roh.beginDraw();
roh.noSmooth();
roh.fill(bckCol);
roh.stroke(normCol);
roh.ellipse(7,7,14,14);
roh.endDraw();
rohy = new PGraphics[4];
for (int i = 0 ; i < rohy.length;i++) {
rohy[i] = createGraphics(roh.width, roh.height, JAVA2D);
rohy[i].beginDraw();
rohy[i].noSmooth();
rohy[i].imageMode(CENTER);
rohy[i].translate(roh.width/2, roh.height/2);
rohy[i].rotate(HALF_PI*i);
rohy[i].image(roh,0,0);
rohy[i].endDraw();
}
name = engine.getUnit(id).name+"";
pos = new PVector(engine.layoutX[id], engine.layoutY[id]);
initSliders();
for (int i =0 ;i<50;i++)
addToPipeline();
}
void draw() {
ready = engine.getUnit(id).ready;
percent = engine.getUnit(id).percent;
//if (ready)
updateFields();
drawBorder();
for (int i =0 ; i < sliders.size(); i++) {
Slider s = (Slider)sliders.get(i);
s.draw();
}
}
void addToPipeline() {
ImageMasher tmp = (ImageMasher)engine.getUnit(id);
tmp.addFilter((int)random(15));
//println(tmp.pipeline.size());
}
void harvestFields() {
ctlFields = new ArrayList();
unit = engine.getUnit(id);
myClass = unit.getClass();
fields = myClass.getDeclaredFields();
for (int ii = 0; ii < parent.DEFAULT_NAMES.length; ii++) {
for (int i = 0; i < fields.length; i++) {
if (fields[i].getName().equals(parent.DEFAULT_NAMES[ii])) {
//println("got "+parent.DEFAULT_NAMES[ii]);
ctlFields.add(fields[i]);
}
}
}
}
void initSliders() {
sliders = new ArrayList();
harvestFields();
for (int i =0;i<ctlFields.size();i++) {
Field tmp = (Field)ctlFields.get(i);
sliders.add(new Slider(this, tmp.getName(), 0, parent.rozpal*i, parent.mins[i], parent.maxs[i], parent.defaults[i]));
}
}
void updateFields() {
for (int i =0;i<ctlFields.size();i++) {
Field tmp = (Field)ctlFields.get(i);
Slider s = (Slider)sliders.get(i);
try {
tmp.set(unit, s.val);
}
catch(IllegalAccessException e) {
}
}
}
void drawBorder() {
rectMode(CORNER);
fill(bckCol);
noStroke();
rect(pos.x+cx+roh.width, pos.y+cy, wx+w-roh.width, parent.rozpal*sliders.size()+roh.height);
rect(pos.x+cx, pos.y+cy+roh.height, wx+w+roh.width, parent.rozpal*sliders.size()-roh.height);
stroke(255);
image(rohy[0], pos.x+cx, pos.y+cy);
image(rohy[1], pos.x+w+wx+cx, pos.y+cy);
image(rohy[2], pos.x+w+wx+cx, pos.y+sliders.size()*parent.rozpal+cy);
image(rohy[3], pos.x+cx, pos.y+sliders.size()*parent.rozpal+cy);
// horizontal
line(pos.x+cx+roh.width, pos.y+cy, pos.x+cx+wx+w, pos.y+cy);
line(pos.x+cx+roh.width, pos.y+cy+parent.rozpal*sliders.size()+roh.height-1, pos.x+cx+wx+w, pos.y+cy+parent.rozpal*sliders.size()+roh.height-1);
// vertical
line(pos.x+cx, pos.y+cy+roh.height, pos.x+cx, pos.y+cy+parent.rozpal*sliders.size() );
line(pos.x+cx+wx+roh.width+w-1, pos.y+cy+roh.height, pos.x+cx+wx+roh.width+w-1, pos.y+cy+parent.rozpal*sliders.size() );
noStroke();
fill(255);
if (!ready) {
arc(pos.x+cx+wx+w-2, pos.y+cy+10, 10, 10, 0, map(percent, 0, 100, 0, TWO_PI));
}
}
}
import java.lang.reflect.*;
boolean mousedown = false;
class GUI {
///////////////////////////////////
///////////////////////////////////
String DEFAULT_NAMES[] = {
"R",
"G",
"B",
"alpha",
"blink_speed",
"shake_speed",
"amplitude",
"effect_smooth",
"x",
"y",
};
///////////////////////////////////
float defaults[] = {
255,
255,
255,
100.,
3.0,
40.,
20.,
1.4,
width/2-215,
25,
};
///////////////////////////////////
float mins[] = {
0,
0,
0,
0.1,
300,
300,
1,
0.8,
0,
height,
};
///////////////////////////////////
float maxs[] = {
255,
255,
255,
255,
1,
1,
100,
1.8,
width,
-300,
};
///////////////////////////////////
///////////////////////////////////
String BLEND_NAMES [] = {
"BLEND",
"ADD",
"SUBTRACT",
"DARKEST",
"LIGHTEST",
"DIFFERENCE",
"EXCLUSION",
"MULTIPLY",
"SCREEN",
"OVERLAY",
"HARD_LIGHT",
"SOFT_LIGHT",
"DODGE",
"BURN"
};
int rozpal = 12;
ArrayList controllers;
TheEngine parent;
GUI(TheEngine _parent) {
parent = _parent;
noSmooth();
textFont(loadFont("SempliceRegular.vlw"));
textMode(SCREEN);
textAlign(LEFT);
resetControllers();
}
void resetControllers() {
controllers = new ArrayList();
for (int i =0 ; i<parent.unit.size();i++) {
addController(i);
}
}
void addController(int _id) {
controllers.add(new Controller(this, _id));
}
void draw() {
for (int i = 0;i<controllers.size();i++) {
Controller c = (Controller)controllers.get(i);
c.draw();
}
}
}
/* Image Masher class
* live visualpha mashing by kof 2011
*/
class ImageMasher implements Runnable {
ArrayList pipeline = new ArrayList();
PVector pos;
int maxW = 450;
float x, y;
float R,G,B;
int scaledown = 1;
float blink_speed = 2.5;
float shake_speed = 10.5;
float amplitude = 20.0;
float alpha = 40;
float effect_smooth = 1.1;
float skvrneni = 3;
int step = 7;
float blurstep = 1.5;
boolean showText = false;
boolean drawBackground = false;
String name;
////////// available filters /////////////////////////////
/*
1: BLEND - linear interpolation of colours: C = A*factor + B
2: ADD - additive blending with white clip: C = min(A*factor + B, 255)
3: SUBTRACT - subtractive blending with black clip: C = max(B - A*factor, 0)
4: DARKEST - only the darkest colour succeeds: C = min(A*factor, B)
5: LIGHTEST - only the lightest colour succeeds: C = max(A*factor, B)
6: DIFFERENCE - subtract colors from underlying image.
7: EXCLUSION - similar to DIFFERENCE, but less extreme.
8: MULTIPLY - Multiply the colors, result will alphaways be darker.
9: SCREEN - Opposite multiply, uses inverse valphaues of the colors.
10: OVERLAY - A mix of MULTIPLY and SCREEN. Multiplies dark valphaues, and screens light valphaues.
11: HARD_LIGHT - SCREEN when greater than 50% gray, MULTIPLY when lower.
12: SOFT_LIGHT - Mix of DARKEST and LIGHTEST. Works like OVERLAY, but not as harsh.
13: DODGE - Lightens light tones and increases conshaket, ignores darks. Calphaled "Color Dodge" in Illustrator and Photoshop.
14: BURN - Darker areas are applied, increasing conshaket, ignores lights. Calphaled "Color Burn" in Illustrator and Photoshop.
*/
PImage img;
int sel =0;
int t = 0, p = 0;
boolean fadeIn = true;
boolean fadeOut;
boolean pause = true;
int pauseLen = 10;
PGraphics steps[];
boolean ready = false;
int id;
float percent = 0;
ImageMasher(int _id, String _filename) {
name = ""+_filename;
id = _id;
x = width/2;
y = height/2;
// obligatory 19
noiseSeed(19);
}
ImageMasher(int _id, PImage _img) {
img = _img;
name = _id+"";
id = _id;
x = width/2;
y = height/2;
// obligatory 19
noiseSeed(19);
}
void addFilter(int _in) {
//println("adding filter "+pipeline.size());
pipeline.add(_in);
}
public boolean isReady() {
return ready;
}
void run() {
img = loadImage(name);
while (img.width/ (scaledown+.0)>maxW) {
scaledown++;
}
steps = new PGraphics[step];
//render blurring here
preRender();
//pipeline = new ArrayList();
//pipeline.add(1);
}
/**
* set new position to image
*/
void setPos(float _x, float _y) {
x=_x;
y = _y;
}
/**
* pre-prepare image
*/
void preRender() {
for (int i =0 ; i < steps.length;i++) {
steps[i] = createGraphics(img.width/scaledown, img.height/scaledown, P2D);
steps[i].beginDraw();
//steps[i].tint(i%2==0?#FFCCCC:#CCFFAA, 200);
steps[i].image(img, 0, 0, img.width/scaledown, img.height/scaledown);
for (int q = 0;q<img.width/scaledown*img.height/scaledown;q+=(int)random(1,120)) {
steps[i].strokeWeight(i*3+1);
steps[i].stroke(0, random(skvrneni*i)+4);
steps[i].point((int)(q%img.width/scaledown), (int)q/img.width/scaledown);
;
}
steps[i].stroke(0);
steps[i].noFill();
steps[i].strokeWeight(20);
steps[i].rect(0, 0, img.width/scaledown, img.height/scaledown);
if (i>0)
steps[i].filter(BLUR, (pow(i, blurstep)));
steps[i].endDraw();
percent = map(i,0,steps.length-1,0,100);
}
ready = true;
}
/**
* draw visualphas
*/
void draw() {
if (drawBackground)
background(0);
if (pipeline.size()>0)
for (int i =0 ; i < steps.length;i++) {
tint(R,G,B, noise((frameCount+i)/shake_speed)*alpha-constrain(pow(i, effect_smooth), 0, 255));
int curr = (int)(Integer)pipeline.get((int)(noise((frameCount+i)/(blink_speed))*pipeline.size()));
if (i==0)
image(steps[i], (noise((frameCount+i^i)/shake_speed)-0.5)*amplitude+x, y+((noise((frameCount+2000+i^i)/shake_speed)-0.5)*amplitude), steps[i].width, steps[i].height);
else
blend(steps[i],
0, 0,
steps[i].width, steps[i].height,
(int)((noise((frameCount+i^i)/shake_speed)-0.5)*amplitude)+(int)x, (int)y+(int)((noise((frameCount+2000+i^i)/shake_speed)-0.5)*amplitude),
steps[i].width, steps[i].height,
curr);
}
noTint();
}
}
/**
* by kof 2011 copyleft
*/
TheEngine engine;
void setup() {
size(640, 480 ,P2D);
engine = new TheEngine();
engine.addImage("vertov2.jpg");
engine.addImage("vertov3.jpg");
background(0);
}
void draw() {
rectMode(CORNER);
noStroke();
fill(0,5);
rect(0,0,width,height);
engine.draw();
}
class Slider {
Controller parent;
float val;
float minval, maxval;
PVector pos;
String name;
int w;
boolean over;
float absX;
float absY;
float def;
Slider(Controller _parent, String _name, float _x, float _y, float _minval, float _maxval,float _def) {
def = _def;
parent = _parent;
name = ""+_name;
pos = new PVector(_x, _y);
minval = _minval;
maxval = _maxval;
absX = pos.x+parent.pos.x;
absY = pos.y+parent.pos.y;
w = parent.w;
val = _def;
}
void draw() {
absX = pos.x+parent.pos.x;
absY = pos.y+parent.pos.y;
over = isOver();
if (over&&mousedown) {
val = minval>maxval?
constrain(map(mouseX, absX, w+absX, minval, maxval),maxval,minval):
constrain(map(mouseX, absX, w+absX, minval, maxval),minval,maxval);
}
if (parent.ready) {
if (over) {
stroke(parent.overCol);
fill(parent.overCol);
}
else {
stroke(parent.normCol);
fill(parent.normCol);
}
}
else {
stroke(parent.normCol, 120);
fill(parent.normCol, 120);
}
rectMode(CENTER);
text(name, absX+w+10, absY);
noFill();
line(absX, absY, w+absX, absY);
rect(map(val,minval,maxval,absX,absX+w), absY, 3, 5);
}
boolean isOver() {
if (mouseX>absX-5&&mouseX<absX+w+20&&mouseY>absY-5&&mouseY<absY+5)
return true;
else
return false;
}
}
void mousePressed() {
mousedown = true;
}
void mouseReleased() {
mousedown = false;
}
/**
* The Engine class scheduling new Threads
* for pre-redering image layers
*/
class TheEngine {
ArrayList unit;
ArrayList names;
GUI gui;
Thread thread;
int[] layoutX = {
20, 420
};
int[] layoutY = {
height-130, height-130
};
TheEngine() {
unit = new ArrayList();
gui = new GUI(this);
}
void addImage(PImage _src) {
unit.add(new ImageMasher(unit.size(), _src));
gui.addController(unit.size()-1);
thread = new Thread((ImageMasher)unit.get(unit.size()-1));
thread.start();
}
void addImage(String _name) {
unit.add(new ImageMasher(unit.size(), _name));
gui.addController(unit.size()-1);
thread = new Thread((ImageMasher)unit.get(unit.size()-1));
thread.start();
}
ImageMasher getUnit(int _which) {
return (ImageMasher)unit.get(_which);
}
void draw() {
for (int i = 0 ; i < unit.size(); i++) {
ImageMasher one = (ImageMasher)unit.get(i);
if (one.ready)
one.draw();
}
gui.draw();
}
}