Browse Source

initial commit

master
Victor Giers 2 years ago
commit
23f37c2558
28 changed files with 4260 additions and 0 deletions
  1. 293
    0
      ASDFPIXELSORT.pde
  2. 60
    0
      AUECHO.pde
  3. 83
    0
      BRIGHTER.pde
  4. 74
    0
      DARKER.pde
  5. 142
    0
      DISTORTER.pde
  6. 119
    0
      DRAWGENERATIVE.pde
  7. 209
    0
      DRAWSTROKES.pde
  8. 249
    0
      FM.pde
  9. 56
    0
      GRAUZONE.pde
  10. 188
    0
      SLITSCAN.pde
  11. 250
    0
      WZIP.pde
  12. 800
    0
      colorspaces.pde
  13. BIN
      data/0.mp4
  14. BIN
      data/0.png
  15. BIN
      data/1.png
  16. BIN
      data/mask.png
  17. BIN
      data/potrace
  18. 2
    0
      data/saves.sav
  19. 47
    0
      ffmpeg.txt
  20. 48
    0
      fx.pde
  21. 155
    0
      mangler2_0001.pde
  22. 40
    0
      mint.pde
  23. 136
    0
      net.pde
  24. 114
    0
      oscillator.pde
  25. 751
    0
      render_airis.pde
  26. 112
    0
      shader.pde
  27. 153
    0
      source.pde
  28. 179
    0
      ui.pde

+ 293
- 0
ASDFPIXELSORT.pde View File



class ASDFPIXELSORT extends Shader {

ASDFPIXELSORT() {
name = "fxASDFPixelSort";
params.add(new Param("black", 0, 200, new int[]{SIN, LINE, RAMPUPDOWN, TAN, COS}));
params.add(new Param("white", -20000000, -6000000, new int[]{SIN, LINE, RAMPUPDOWN, TAN, COS}));
params.add(new Param("brightness", -15000000, 2000000, new int[]{SIN, LINE, RAMPUPDOWN, TAN, COS}));
params.add(new Param("mode", 3, new int[]{RANDOM}));
}
/*
float playSpeed = 4;
float inc1, inc2, inc3;
void animate() {
inc1+=playSpeed/400;
inc2+=playSpeed/300;
inc3+=playSpeed/350;
if ((frameCount % int(map(playSpeed, 0, 4, 15, 120))) == 0) {
for (int i = 0; i < params.size(); i++)
params.get(i).randomize();
}
params.get(0).setValue((sin(inc1)+1)/2);
params.get(2).setValue((sin(inc2)+1)/2);
params.get(1).setValue((sin(inc3)+1)/2);
}
*/
void apply() {
row = 0;
column = 0;
renderer.beginDraw();
renderer.colorMode(RGB);
colorMode(RGB);
while (column < renderer.width-1) {
renderer.loadPixels();
sortColumn();
column++;
renderer.updatePixels();
}

while (row < renderer.height-1) {
renderer.loadPixels();
sortRow();
row++;
renderer.updatePixels();
}

renderer.endDraw();
}

int row = 0;
int column = 0;
void sortRow() {
int x = 0;
int y = row;
int xend = 0;

while (xend < renderer.width-1) {
switch((int)params.get(3).value) {
case 0:
x = getFirstNotBlackX(x, y);
xend = getNextBlackX(x, y);
break;
case 1:
x = getFirstBrightX(x, y);
xend = getNextDarkX(x, y);
break;
case 2:
x = getFirstNotWhiteX(x, y);
xend = getNextWhiteX(x, y);
break;
default:
break;
}

if (x < 0) break;

int sortLength = xend-x;

color[] unsorted = new color[sortLength];
color[] sorted = new color[sortLength];

for (int i=0; i<sortLength; i++) {
unsorted[i] = renderer.pixels[x + i + y * renderer.width];
}

sorted = sort(unsorted);

for (int i=0; i<sortLength; i++) {
renderer.pixels[x + i + y * renderer.width] = sorted[i];
}

x = xend+1;
}
}


void sortColumn() {
int x = column;
int y = 0;
int yend = 0;

while (yend < renderer.height-1) {
switch((int)params.get(3).value) {
case 0:
y = getFirstNotBlackY(x, y);
yend = getNextBlackY(x, y);
break;
case 1:
y = getFirstBrightY(x, y);
yend = getNextDarkY(x, y);
break;
case 2:
y = getFirstNotWhiteY(x, y);
yend = getNextWhiteY(x, y);
break;
default:
break;
}

if (y < 0) break;

int sortLength = yend-y;
color[] unsorted = new color[sortLength];
color[] sorted = new color[sortLength];
for (int i=0; i<sortLength; i++) {
unsorted[i] = renderer.pixels[x + (y+i) * renderer.width];
}

sorted = sort(unsorted);


for (int i=0; i<sortLength; i++) {
renderer.pixels[x + (y+i) * renderer.width] = sorted[i];
}

y = yend+1;
}
}


//BLACK
int getFirstNotBlackX(int _x, int _y) {
int x = _x;
int y = _y;
color c;
while ( (c = renderer.pixels[x + y * renderer.width]) < params.get(0).value) {
x++;
if (x >= renderer.width) return -1;
}
return x;
}

int getNextBlackX(int _x, int _y) {
int x = _x+1;
int y = _y;
color c;
while ( (c = renderer.pixels[x + y * renderer.width]) > params.get(0).value) {
x++;
if (x >= renderer.width) return renderer.width-1;
}
return x-1;
}

//BRIGHTNESS
int getFirstBrightX(int _x, int _y) {
int x = _x;
int y = _y;
color c;
while (brightness (c = renderer.pixels[x + y * renderer.width]) < params.get(2).value) {
x++;
if (x >= renderer.width) return -1;
}
return x;
}

int getNextDarkX(int _x, int _y) {
int x = _x+1;
int y = _y;
color c;
while (brightness (c = renderer.pixels[x + y * renderer.width]) > params.get(2).value) {
x++;
if (x >= renderer.width) return renderer.width-1;
}
return x-1;
}

//WHITE
int getFirstNotWhiteX(int _x, int _y) {
int x = _x;
int y = _y;
color c;
while ( (c = renderer.pixels[x + y * renderer.width]) > params.get(1).value) {
x++;
if (x >= renderer.width) return -1;
}
return x;
}

int getNextWhiteX(int _x, int _y) {
int x = _x+1;
int y = _y;
color c;
while ( (c = renderer.pixels[x + y * renderer.width]) < params.get(1).value) {
x++;
if (x >= renderer.width) return renderer.width-1;
}
return x-1;
}


//BLACK
int getFirstNotBlackY(int _x, int _y) {
int x = _x;
int y = _y;
color c;
if (y < renderer.height) {
while ( (c = renderer.pixels[x + y * renderer.width]) < params.get(0).value) {
y++;
if (y >= renderer.height) return -1;
}
}
return y;
}

int getNextBlackY(int _x, int _y) {
int x = _x;
int y = _y+1;
color c;
if (y < renderer.height) {
while ( (c = renderer.pixels[x + y * renderer.width]) > params.get(0).value) {
y++;
if (y >= renderer.height) return renderer.height-1;
}
}
return y-1;
}

//BRIGHTNESS
int getFirstBrightY(int _x, int _y) {
int x = _x;
int y = _y;
color c;
if (y < renderer.height) {
while (brightness (c = renderer.pixels[x + y * renderer.width]) < params.get(2).value) {
y++;
if (y >= renderer.height) return -1;
}
}
return y;
}

int getNextDarkY(int _x, int _y) {
int x = _x;
int y = _y+1;
color c;
if (y < renderer.height) {
while (brightness (c = renderer.pixels[x + y * renderer.width]) > params.get(2).value) {
y++;
if (y >= renderer.height) return renderer.height-1;
}
}
return y-1;
}

//WHITE
int getFirstNotWhiteY(int _x, int _y) {
int x = _x;
int y = _y;
color c;
if (y < renderer.height) {
while ( (c = renderer.pixels[x + y * renderer.width]) > params.get(2).value) {
y++;
if (y >= renderer.height) return -1;
}
}
return y;
}

int getNextWhiteY(int _x, int _y) {
int x = _x;
int y = _y+1;
color c;
if (y < renderer.height) {
while ( (c = renderer.pixels[x + y * renderer.width]) < params.get(1).value) {
y++;
if (y >= renderer.height) return renderer.height-1;
}
}
return y-1;
}
}

+ 60
- 0
AUECHO.pde View File

class AUECHO extends Shader {
AUECHO() {
name = "fxAUecho";
params.add(new Param("mode", 2, new int[]{RANDOM}));
params.add(new Param("echo", 0, 255, new int[]{SIN, LINE, RAMPUPDOWN, TAN, COS}));
params.add(new Param("decay", 0, 255, new int[]{SIN, LINE, RAMPUPDOWN, TAN, COS}));
}
/*
float inc1, inc2;
void animate() {
inc1+=.00003;
inc2+=.04;
params.get(1).setValue((sin(inc1)+1)/4);
params.get(2).setValue((sin(inc2)+1)/2);
if (random(1) > .99) {
for (int i = 0; i < params.size(); i++)
params.get(i).randomize();
}
}
*/
void apply() {
renderer.beginDraw();
if (params.get(0).value == 0) {
renderer.colorMode(HSB);
colorMode(HSB);
} else {
renderer.colorMode(RGB);
colorMode(RGB);
}
renderer.loadPixels();
float _delay = map(params.get(1).getValue(params.get(1).value, true), 0, 1, 0.001, 1.0);
float decay = map(params.get(2).getValue(params.get(2).value, true), 0, 1, 0.0, 1.0);
int delay = (int)(renderer.pixels.length * _delay);
color[] history = new color[renderer.pixels.length];
int blendMode = BLEND;
for ( int i = 0, l = renderer.pixels.length; i<l; i++) {
history[i] = renderer.pixels[i];
}
for ( int i = 0, l = renderer.pixels.length; i<l; i++) {
int fromPos = i-delay < 0 ? l-abs(i-delay) : i-delay;
color fromColor = history[fromPos];
float r = red(fromColor) * decay;
float g = green(fromColor) * decay;
float b = blue(fromColor) * decay;
color origColor = history[i];
color toColor = color(
r = r + red(origColor) > 255 ? r + red(origColor) - 255 : r + red(origColor), // simulate overflow ;)
g = g + green(origColor) > 255 ? g + green(origColor) - 255 : g + green(origColor),
b = b + blue(origColor) > 255 ? b + blue(origColor) - 255 : b + blue(origColor) );

renderer.pixels[i] = history[i] = toColor; //blendColor(origColor, toColor, blendMode);
}
renderer.updatePixels();
if (params.get(0).value == 0) {
renderer.colorMode(RGB);
colorMode(RGB);
}
renderer.endDraw();
}
}

+ 83
- 0
BRIGHTER.pde View File


class BRIGHTER extends Shader {

BRIGHTER() {
name = "fxBRIGHTER";

params.add(new Param("mode", 2, new int[]{RANDOM}));
params.add(new Param("thresh", 60, 180, new int[]{SIN, LINE, RAMPUPDOWN, TAN, COS}));
params.add(new Param("thresh2", 120, 200, new int[]{SIN, LINE, RAMPUPDOWN, TAN, COS}));
params.add(new Param("brighten", 140, 220, new int[]{SIN, LINE, RAMPUPDOWN, TAN, COS}));
/*
params.add(new Param("mode", 2));
params.add(new Param("thresh", 60, 180));
params.add(new Param("thresh2", 120, 200));
params.add(new Param("brighten", 140, 220));*/
}

/*
float inc1, inc2, inc3;
float speed;
void animate() {
inc1+=(speed + .006);
inc2+=(speed + .0045);
inc3+=(speed + .002);
//gui.brickP5.getController("knobOne-"+str(brick)).setValue(int(map(sin(inc1), 2, -1, 0, 255)));
//gui.brickP5.getController("knobTwo-"+str(brick)).setValue(int(map(cos(inc2), -1, 1, 0, 255)));
//if (mode == 0) {
// gui.brickP5.getController("knobThree-"+str(brick)).setValue(int(map(cos(inc2), -1, 1, 0, int(map(cos(inc2), -1, 1, 0, 255)))));
//} else if (mode == 1) {

// gui.brickP5.getController("knobThree-"+str(brick)).setValue(int(map(cos(inc2), -1, 1, int(map(cos(inc2), -1, 1, 0, 255)), 255 )));
//}

if (random(1) > .99) {
for (int i = 0; i < params.size(); i++)
params.get(i).randomize();
}
}
*/
void apply() {
int mode = (int)params.get(0).value;
float brighten = params.get(1).value;
float thresh = params.get(2).value;
float thresh2 = params.get(3).value;



renderer.beginDraw();
renderer.colorMode(HSB);
colorMode(HSB);
renderer.loadPixels();
if (mode == 0) {
for (int i = 0; i < renderer.width*renderer.height; i++) {
float hue = hue(renderer.pixels[i]);
float sat = saturation(renderer.pixels[i]);
float bright = brightness(renderer.pixels[i]);
if (bright < thresh && bright > thresh2) {
bright += brighten;
constrain(bright, 0, 255);
}
color c = color(hue, sat, bright);
renderer.pixels[i] = c;
}
} else if (mode == 1) {
for (int i = 0; i < renderer.width*renderer.height; i++) {
float hue = hue(renderer.pixels[i]);
float sat = saturation(renderer.pixels[i]);
float bright = brightness(renderer.pixels[i]);
if (bright > thresh && bright < thresh2) {
bright += brighten;
constrain(bright, 0, 255);
}
color c = color(hue, sat, bright);
renderer.pixels[i] = c;
}
}
renderer.updatePixels();
renderer.colorMode(RGB);
colorMode(RGB);
renderer.endDraw();
}
}

+ 74
- 0
DARKER.pde View File


class DARKER extends Shader {

DARKER() {
name = "fxDARKER";
/*
params.add(new Param ("layers", 5));
params.add(new Param ("thresh", 0, 255));
params.add(new Param ("value", 0, 255));
params.add(new Param ("mode", 2));*/
}

float inc1, inc2;
float playSpeed = 4;

void animate() {
inc1+=playSpeed/400;
inc2+=playSpeed/300;
if ((frameCount % int(map(playSpeed, 0, 4, 15, 120))) == 0) {
for (int i = 0; i < params.size(); i++)
params.get(i).randomize();
}
params.get(1).setValue((sin(inc1)+1)/2);
params.get(2).setValue((sin(inc2)+1)/2);
}

void apply() {
float h, s, b;
renderer.beginDraw();
renderer.colorMode(HSB);
renderer.loadPixels();
colorMode(HSB);
if (params.get(3).value == 0) {
for (int j = 1; j < params.get(0).value+1; j++) {
for (int i = 0; i < renderer.width*renderer.height; i++) {
h = hue(renderer.pixels[i]);
s = saturation(renderer.pixels[i]);
b = brightness(renderer.pixels[i]);
if (b > params.get(1).value/j);
{
if (!(h == 85.0 && s == 255.0 && b == 255.0)) {
b -= params.get(2).value/j;
constrain(b, 0, 255);
color c = color(h, s, b);
renderer.pixels[i] = c;
}
}
}
}
} else if (params.get(3).value == 1) {
for (int j = 1; j < params.get(0).value+1; j++) {
for (int i = 0; i < renderer.width*renderer.height; i++) {
h = hue(renderer.pixels[i]);
s = saturation(renderer.pixels[i]);
b = brightness(renderer.pixels[i]);

if (b < params.get(1).value/j) {
if (!(h == 85.0 && s == 255.0 && b == 255.0));
{
b -= params.get(2).value/j;
constrain(b, 0, 255);
}
}
color c = color(h, s, b);
renderer.pixels[i] = c;
}
}
}
renderer.updatePixels();
renderer.colorMode(RGB);
renderer.endDraw();
colorMode(RGB);
}
}

+ 142
- 0
DISTORTER.pde View File

class DISTORTER extends Shader {

PImage buffer;

int[][] distort = new int[2][512];
final static float tick = 1.0/512.0;
final int[] blends = {
ADD, SUBTRACT, DARKEST, LIGHTEST, DIFFERENCE, EXCLUSION, MULTIPLY, SCREEN, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN
};
// ALL Channels, Nxxx stand for negative (255-value)
// channels to work with
final static int RED = 0;
final static int GREEN = 1;
final static int BLUE = 2;
final static int HUE = 3;
final static int SATURATION = 4;
final static int BRIGHTNESS = 5;
final static int NRED = 6;
final static int NGREEN = 7;
final static int NBLUE = 8;
final static int NHUE = 9;
final static int NSATURATION = 10;
final static int NBRIGHTNESS = 11;

DISTORTER() {
name = "fxDistorter";
/*
//params.add(new Param ("shifthue", 1)); //boolean shift_hue
params.add(new Param("hueshift", 0, 1)); //float shift_amt
params.add(new Param("scalex", 0.01, 1)); //float scalex
params.add(new Param("scaley", 0.01, 1)); //float scaley
//params.add(new Param ("blend", 1)); //boolean do_blend
params.add(new Param ("blendmode", blends.length)); //int blend_mode
params.add(new Param("channel", 12));*/

buffer = createImage(renderer.width, renderer.height, ARGB);

// prepare distortion pattern
for (int i=0; i<512; i++) {
distort[0][i] = (int)random(-128, 128);
distort[1][i] = (int)random(-128, 128);
}
}

float inc1, inc2;
void animate() {
inc1+=.03;
inc2+=.04;
params.get(1).setValue((sin(inc1)+1)/2);
params.get(2).setValue((sin(inc2)+1)/2);
if (random(1) > .99) {
for (int i = 0; i < params.size(); i++)
params.get(i).randomize();
}
}

void apply() {
buffer = renderer.get();
buffer.resize(renderer.width, renderer.height);

float neww = map(params.get(1).value, 0, 1, 1, buffer.width/4);
float newh = map(params.get(2).value, 0, 1, 1, buffer.height/4);

float totalnum = neww+newh;
float times = (totalnum/floor(totalnum/neww));
float offx = (totalnum%neww)/times;
float ratiox = neww/buffer.width;

renderer.beginDraw();
renderer.noStroke();

for (int y=0; y<buffer.height; y++) {
float yy = y/(float)buffer.height;
for (int x=0; x<buffer.width; x++) {
float xx = x/(float)buffer.width;

float offy = floor(newh*yy);
float fx = xx*ratiox+offx*offy;

float shift = fx%1.0;
float st = shift/tick;
int no1 = floor(st)%512;
int no2 = ceil(st)%512;
float l = st-(float)no1;

float cx = lerp(distort[0][no1], distort[0][no2], l);
float cy = lerp(distort[1][no1], distort[1][no2], l);

float rx =getChannel(buffer.get(x, y), (int)params.get(4).value);
int sx = (int)((buffer.width+x+cx*rx*params.get(1).value*0.1)%buffer.width);
int sy = (int)((buffer.height+y+cy*params.get(0).value)%buffer.height);

color c=buffer.get(sx, sy);

//if (boolean((int)(params.get(0).value))) {
colorMode(HSB, 255);
c = color((hue(c)+params.get(0).value*255*noise(newh+y))%255.0, constrain(saturation(c)*1.2, 0, 255), constrain(brightness(c), 0, 255));
colorMode(RGB, 255);
//}
//renderer.fill(lerpColor(c,buffer.get(x,y),0.2));
renderer.fill(c);
renderer.rect(x, y, 1, 1);
}
}

//if (boolean((int)(params.get(4).value)))
renderer.blend(buffer, 0, 0, buffer.width, buffer.height, 0, 0, renderer.width, renderer.height, (int)params.get(3).value);

colorMode(RGB);
renderer.endDraw();
}



float getChannel(color c, int channel) {
int ch = channel>5?channel-6:channel;
float cc;

switch(ch) {
case RED:
cc = red(c);
break;
case GREEN:
cc = green(c);
break;
case BLUE:
cc = blue(c);
break;
case HUE:
cc = hue(c);
break;
case SATURATION:
cc = saturation(c);
break;
default:
cc= brightness(c);
break;
}

return channel>5?255-cc:cc;
}
}

+ 119
- 0
DRAWGENERATIVE.pde View File

class DRAWGENERATIVE extends Shader {

// choose channel
int channel = HUE;

// run, after 30 iterations result will be saved automatically
// or press SPACE


// channels to work with
final static int RED = 0;
final static int GREEN = 1;
final static int BLUE = 2;
final static int HUE = 3;
final static int SATURATION = 4;
final static int BRIGHTNESS = 5;
final static int NRED = 6;
final static int NGREEN = 7;
final static int NBLUE = 8;
final static int NHUE = 9;
final static int NSATURATION = 10;
final static int NBRIGHTNESS = 11;

int n=2000;
float [] cx=new float[n];
float [] cy=new float[n];

int len;

// working buffer
PGraphics buffer;


int tick = 0;


DRAWGENERATIVE() {
name = "fxDrawGenerative";
buffer = createGraphics(renderer.width, renderer.height);
buffer.noFill();
buffer.beginDraw();
buffer.strokeWeight(0.3);
//buffer.background(0); //ENABLE THIS TO DRAW FROM BLANK
buffer.endDraw();
rw = renderer.width;
len = (renderer.width<renderer.height?renderer.width:renderer.height)/6;

for (int i=0; i<n; i++) {
cx[i]=random(renderer.width);
cy[i]=random(renderer.height);
}
}

int rw;
void apply() {
if (rw != renderer.width) {
rw = renderer.width;
PGraphics save = createGraphics(renderer.width, renderer.height);
save.beginDraw();
save.image(buffer, 0, 0, save.width, save.height);
save.endDraw();
buffer.setSize(renderer.width, renderer.height);
buffer.beginDraw();
buffer.image(save,0,0,buffer.width,buffer.height);
buffer.endDraw();
}
buffer.beginDraw();
for (int i=1; i<n; i++) {
color c = renderer.get((int)cx[i], (int)cy[i]);
buffer.stroke(c);
buffer.point(cx[i], cy[i]);
// you can choose channels: red(c), blue(c), green(c), hue(c), saturation(c) or brightness(c)
cy[i]+=sin(map(getChannel(c), 0, 255, 0, TWO_PI));
cx[i]+=cos(map(getChannel(c), 0, 255, 0, TWO_PI));
}
if (frameCount>len) {
frameCount=0;
println("iteration: " + tick++);
for (int i=0; i<n; i++) {
cx[i]=random(renderer.width);
cy[i]=random(renderer.height);
}
}
buffer.endDraw();
renderer.beginDraw();
renderer.image(buffer, 0, 0, renderer.width, renderer.height);
renderer.endDraw();
}


float getChannel(color c) {
int ch = channel>5?channel-6:channel;
float cc;

switch(ch) {
case RED:
cc = red(c);
break;
case GREEN:
cc = green(c);
break;
case BLUE:
cc = blue(c);
break;
case HUE:
cc = hue(c);
break;
case SATURATION:
cc = saturation(c);
break;
default:
cc= brightness(c);
break;
}

return channel>5?255-cc:cc;
}
}

+ 209
- 0
DRAWSTROKES.pde View File

class DRAWSTROKES extends Shader {

int stat_type = ABSDIST2; // type of diff calculation: fast: ABSDIST, DIST, slow: HUE, SATURATION, BRIGHTNESS
int stroke_len = 3; // length of the stroke, values: 1 and above
int angles_no = 30; // number of directions stroke can be drew, 2 and above
int segments = 500; // number of segments of single thread
float stroke_width = 1; // width of the stroke, 0.5 - 3
int stroke_alpha = 100; // alpha channel of the stroke: 30 - 200

color background_color = color(255, 255, 255); // RGB

boolean interactive = false;
int max_display_size = 800; // viewing window size (regardless image size)

int len;
// working buffer
PGraphics buffer;

int currx, curry;
int[] sintab, costab;
int sqwidth;

int calcDiff(PImage img1, PImage img2) {
int err = 0;
for (int i=0; i<img1.pixels.length; i++)
err += getStat(img1.pixels[i], img2.pixels[i]);
return err;
}

DRAWSTROKES() {
name = "fxDrawStrokes";
/*
params.add(new Param ("stat_type", 6)); //0 bis 5, 4 und 5 sind mit abstand am schnellsten
params.add(new Param ("stroke_len", 1, 15));
params.add(new Param ("angles_no", 2, 50));
params.add(new Param ("segments", 50, 1500));
params.add(new Param ("stroke_width", 0.5, 3));
params.add(new Param ("stroke_alpha", 50, 200));
*/
params.get(0).randomize();
params.get(1).randomize();
params.get(2).randomize();
params.get(3).randomize();
params.get(4).randomize();
params.get(5).randomize();




len = (renderer.width<renderer.height?renderer.width:renderer.height)/3;

buffer = createGraphics(renderer.width, renderer.height);
//buffer.smooth(8);
buffer.beginDraw();
buffer.background(255);
buffer.noFill();
buffer.endDraw();

rw = renderer.width;


reinit();
}

void reinit() {
buffer.beginDraw();
buffer.strokeWeight(stroke_width);
//buffer.background(background_color); //ENABLE THIS TO DRAW FROM BLANK
buffer.endDraw();

currx = (int)random(renderer.width);
curry = (int)random(renderer.height);

sintab = new int[angles_no];
costab = new int[angles_no];

for (int i=0; i<angles_no; i++) {
sintab[i] = (int)(stroke_len * sin(TWO_PI*i/(float)angles_no));
costab[i] = (int)(stroke_len * cos(TWO_PI*i/(float)angles_no));
}

sqwidth = stroke_len * 2 + 4;
}

void animate() {
if (random(1) > .99) {
for (int i = 0; i < params.size(); i++)
params.get(i).randomize();
stat_type = (int)params.get(0).value;
stroke_len = (int)params.get(1).value;
angles_no = (int)params.get(2).value;
segments = (int)params.get(3).value;
stroke_width = params.get(4).value;
stroke_alpha = (int)params.get(5).value;
reinit();
}
}

int rw;
void apply() {
if (rw != renderer.width) {
rw = renderer.width;
PGraphics save = createGraphics(renderer.width, renderer.height);
save.beginDraw();
save.image(buffer, 0, 0, save.width, save.height);
save.endDraw();
buffer.setSize(renderer.width, renderer.height);
buffer.beginDraw();
buffer.image(save, 0, 0, buffer.width, buffer.height);
buffer.endDraw();
}
currx = (int)random(renderer.width);
curry = (int)random(renderer.height);

buffer.beginDraw();
//draw whole segment using current color
buffer.stroke(renderer.get(currx, curry), stroke_alpha);

for (int iter=0; iter<segments; iter++) {
// corners of square containing new strokes
int corx = currx-stroke_len-2;
int cory = curry-stroke_len-2;

// take square from image and current screen
PImage imgpart = renderer.get(corx, cory, sqwidth, sqwidth);
PImage mypart = buffer.get(corx, cory, sqwidth, sqwidth);
imgpart.loadPixels();
mypart.loadPixels();

// calc current diff
float localerr = calcDiff(imgpart, mypart);

// chosen stroke will be here
PImage destpart = null;
int _nx=currx, _ny=curry;

// start with random angle
int i = (int)random(angles_no);
int iterangles = angles_no;

while (iterangles-- > 0) {
// take end points
int nx = currx + costab[i];
int ny = curry + sintab[i];

// if not out of the screen
if (nx>=0 && nx<renderer.width-1 && ny>=0 && ny<renderer.height-1) {
// clean region and draw line
buffer.image(mypart, corx, cory);
buffer.line(currx, curry, nx, ny);

// take region with line and calc diff
PImage curr = buffer.get(corx, cory, sqwidth, sqwidth);
curr.loadPixels();
int currerr = calcDiff(imgpart, curr);

// if better, remember this region and line endpoint
if (currerr < localerr) {
destpart = curr;
_nx = nx;
_ny = ny;
localerr = currerr;
}
}

// next angle
i = (i+1)%angles_no;
}

// if we have new stroke, draw it
if (destpart != null) {
buffer.image(destpart, corx, cory);
currx = _nx;
curry = _ny;
} else {
break; // skip
}
}

buffer.endDraw();
renderer.beginDraw();
renderer.image(buffer, 0, 0, renderer.width, renderer.height);
renderer.endDraw();
}

final static int DIST = 0;
final static int HUE = 1;
final static int BRIGHTNESS = 2;
final static int SATURATION = 3;
final static int ABSDIST = 4;
final static int ABSDIST2 = 5;

final float getStat(color c1, color c2) {
switch(stat_type) {
case HUE:
abs(hue(c1)-hue(c2));
case BRIGHTNESS:
abs(brightness(c1)-brightness(c2));
case SATURATION:
abs(saturation(c1)-saturation(c2));
case ABSDIST:
return abs(red(c1)-red(c2))+abs(green(c1)-green(c2))+abs(blue(c1)-blue(c2));
case ABSDIST2:
return abs( (red(c1)+blue(c1)+green(c1)) - (red(c2)+blue(c2)+green(c2)) );
default:
return sq(red(c1)-red(c2)) + sq(green(c1)-green(c2)) + sq(blue(c1)-blue(c2));
}
}
}

+ 249
- 0
FM.pde View File

// FM - frequency modulator
// 2016 Tomasz Sulej, generateme.blog@gmail.com, http://generateme.tumblr.com
// Licence: http://unlicense.org/

// Frequency modulation and demodulation of the image
// process goes in following way:
// - convert RGB into desired colorspace (GS - grayscale)
// For every channel
// - modulate signal
// - quantize and dequantize signal (if quantval > 0)
// - demodulate signal using derivative method
// - apply 3 lowpass filters in a chain to remove carrier (if possible)
// Combine channels and convert back to RGB

// Usage:
// * move mouse X axis - change the carrier wave frequency
// * move mouse Y axis - change bandwidth
// * click mouse to fix setup (click again to release)
// * press N to negate image
// * press SPACE to save


class FM extends Shader {
// configuration
int colorspace = RGB;
final static boolean first_channel_only = false; // for L.. or Y.. colorspaces set true to modulate only luma;
final static int quantval = 30; // 0 - off, less - more glitch, more - more precision
final static boolean lowpass1_on = true; // on/off of first low pass filter
final static boolean lowpass2_on = true; // on/off of second low pass filter
final static boolean lowpass3_on = true; // on/off of third low pass filter

// better don't touch it, lowpass filters are run in cascade
float lowpass1_cutoff = 0.25; // percentage of rate
float lowpass2_cutoff = 0.1;
float lowpass3_cutoff = 0.05;

boolean do_blend = true; // blend image after process
int blend_mode = OVERLAY; // blend type

// working buffer
PGraphics buffer;

// image
//PImage img;

// local variables
float min_omega, max_omega;
float min_phase_mult=0.05;
float max_phase_mult=50.0;
LowpassFilter lpf1, lpf2, lpf3;
int[][] pxls;
boolean negate = false;

FM() {
name = "fxFM";
//img = loadImage(foldername+filename+fileext);
params.add(new Param ("blend_mode", 11, new int[]{RANDOM}));
params.add(new Param ("omega", 0, 1, new int[]{SIN, LINE}));
params.add(new Param ("phase", 0, 1, new int[]{LINE, SIN, TAN, RAMPUPDOWN, RAMP}));
params.get(0).randomize();
params.get(1).randomize();
params.get(2).randomize();

buffer = createGraphics(renderer.width, renderer.height);
buffer.beginDraw();
buffer.noStroke();
//buffer.smooth(8);
//buffer.background(0);
// buffer.image(renderer, 0, 0);
buffer.endDraw();

//img.loadPixels();

min_omega = TWO_PI/(0.05*renderer.width);
max_omega = TWO_PI/(300.0*renderer.width);

float rate = 100000.0;

lpf1 = new LowpassFilter(rate, lowpass1_cutoff*rate);
lpf2 = new LowpassFilter(rate, lowpass2_cutoff*rate);
lpf3 = new LowpassFilter(rate, lowpass3_cutoff*rate);

rw = renderer.width;
prepareData();
}
//float inc1, inc2;
//float playSpeed = 4;
/*
void animate() {
blend_mode = (int)params.get(0).value + 2;
inc1+=playSpeed/400;
inc2+=playSpeed/300;
if ((frameCount % int(map(playSpeed, 0, 4, 15, 120))) == 0) {
for (int i = 0; i < params.size(); i++)
params.get(i).randomize();
}
params.get(1).setValue((sin(inc1)+1)/2);
params.get(2).setValue((sin(inc2)+1)/2);
}
*/
void prepareData() {
pxls = new int[3][renderer.pixels.length];
for (int i=0; i<renderer.pixels.length; i++) {
int cl = toColorspace(renderer.pixels[i], colorspace);
pxls[0][i] = (cl >> 16) & 0xff;
pxls[1][i] = (cl >> 8) & 0xff;
pxls[2][i] = (cl) & 0xff;
}
}

float omega, min_phase, max_phase;


int rw, rh;
void apply() {
if (rw != renderer.width || rh != renderer.height) {
rw = renderer.width;
rh = renderer.height;
min_omega = TWO_PI/(0.05*renderer.width);
max_omega = TWO_PI/(300.0*renderer.width);
prepareData();
}
buffer.setSize(renderer.width, renderer.height);

omega = map(sqrt(params.get(1).value), 0, 1, min_omega, max_omega);

float phase = map(sq(params.get(2).value), 0, 1, min_phase_mult, max_phase_mult);
max_phase = phase * omega;
min_phase = -max_phase;

processImage();
}

void processImage() {
buffer.beginDraw();
buffer.loadPixels();

int [][] dest_pxls = new int[3][renderer.pixels.length];

if (first_channel_only) {
arrayCopy(pxls[1], dest_pxls[1]);
arrayCopy(pxls[2], dest_pxls[2]);
}

for (int i=0; i< (first_channel_only?1:3); i++) {
for (int y=0; y<renderer.height; y++) {
int off = y * renderer.width;

//reset filters each line
lpf1.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
lpf2.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
lpf3.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));

float sig_int = 0; // integral of the signal
float pre_m = 0; // previous value of modulated signal

for (int x=0; x<renderer.width; x++) {

/////////////////////////
// FM part starts here
/////////////////////////

float sig = map(pxls[i][x+off], 0, 255, min_phase, max_phase); // current signal value
sig_int += sig; // current value of signal integral

float m = cos(omega * x + sig_int); // modulate signal

if ( quantval > 0) {
m = map((int)map(m, -1, 1, 0, quantval), 0, quantval, -1, 1); // quantize
}

float dem = abs(m-pre_m); // demodulate signal, derivative
pre_m = m; // remember current value

// lowpass filter chain
if (lowpass1_on) dem = lpf1.lowpass(dem);
if (lowpass2_on) dem = lpf2.lowpass(dem);
if (lowpass3_on) dem = lpf3.lowpass(dem);

// remap signal back to channel value
int v = constrain( (int)map(2*(dem-omega), min_phase, max_phase, 0, 255), 0, 255);

//////////////////////
// FM part ends here
//////////////////////

dest_pxls[i][x+off] = negate?255-v:v;
}
}
}

for (int i=0; i<buffer.pixels.length; i++) {
buffer.pixels[i] = fromColorspace(0xff000000 | (dest_pxls[0][i] << 16) | (dest_pxls[1][i] << 8) | (dest_pxls[2][i]), colorspace);
}

buffer.updatePixels();

if (do_blend)
buffer.blend(renderer, 0, 0, renderer.width, renderer.height, 0, 0, buffer.width, buffer.height, blend_mode);

buffer.endDraw();
renderer.beginDraw();
renderer.image(buffer, 0, 0, renderer.width, renderer.height);
renderer.endDraw();
}


//

final int[] blends = {
ADD, SUBTRACT, DARKEST, LIGHTEST, DIFFERENCE, EXCLUSION, MULTIPLY, SCREEN, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN
};

class LowpassFilter {
float alpha;
float prev;

public LowpassFilter(float rate, float hz) {
alpha = 0.0;
prev = 0.0;
setFilter(rate, hz);
}

void setFilter(float rate, float hz) {
float timeInterval = 1.0/rate;
float tau = 1.0 / (hz * TWO_PI);
alpha = timeInterval / (tau + timeInterval);
}

void resetFilter(float val) {
prev = val;
}

void resetFilter() {
resetFilter(0);
}

float lowpass(float sample) {
float stage1 = sample * alpha;
float stage2 = prev - (prev * alpha);
prev = (stage1 + stage2);
return prev;
}

float highpass(float sample) {
return sample - lowpass(sample);
}
}
}

+ 56
- 0
GRAUZONE.pde View File

class GRAUZONE extends Shader {
float inc1, inc2;
int nFrames = 20;
int iWrite = 0, iRead = 1;
PImage[] buffer;
PGraphics grauz;
GRAUZONE() {
name = "fxGRAUZONE";
//params.add(new Param ("discance", 3, 100));
params.get(0).setValue(.2);
buffer = new PImage[nFrames];
}
void animate() {
inc1+=.03;
inc2+=.04;
//params.get(0).setValue((sin(inc1)+1)/2);
if (random(1) > .99) {
for (int i = 0; i < params.size(); i++)
params.get(i).randomize();
}

iWrite++;
iRead++;
if (iRead >= nFrames-1) {
iRead = 0;
}
if (iWrite >= nFrames-1) {
iWrite = 0;
}
}
void apply() {



//buffer[iWrite] = renderer.get();
grauz = createGraphics(renderer.width, renderer.height);
grauz.beginDraw();
// grauz.resize(renderer.width, renderer.height);
buffer[iWrite] = renderer.get();
if (buffer[iRead] != null) {
grauz.tint(255, 127);
if (this.animating) {
buffer[iRead].filter(INVERT);
}
grauz.image(buffer[iRead], 0, 0, renderer.width, renderer.height);
grauz.tint(255, 255);
}
grauz.endDraw();



renderer.beginDraw();
renderer.image(grauz, 0, 0, renderer.width, renderer.height);
renderer.endDraw();
}
}

+ 188
- 0
SLITSCAN.pde View File


class SLITSCAN extends Shader {
int[] fx;
int[] fy;
float[] phx;
float[] phy;
int[] sx, sy;
boolean[] skipfx;
boolean[] skipfy;
boolean dox, doy;
PImage buffer;
float[][] ft = new float[2][32];
int depth; // number of octaves
int fxnum;
int fynum;
SLITSCAN() {
name = "fxSlitSscan";
buffer = createImage(renderer.width, renderer.height, ARGB);
for (int i=0; i<32; i++) {
ft[0][i] = pow(2.0, i);
ft[1][i] = 0.5*1.0/ft[0][i];
}
}

void animate() {

buffer.resize(renderer.width, renderer.height);
buffer = renderer.get(0, 0, renderer.width, renderer.height);
int s = buffer.width>buffer.height?buffer.height:buffer.width;
depth = (int)(log(s)/log(2));
fxnum = (int)random(depth);
fynum = (int)random(depth);


fx = new int[fxnum+1];
fy = new int[fynum+1];
sx = new int[fxnum+1];
sy = new int[fynum+1];

phx = new float[fxnum+1];
phy = new float[fynum+1];

skipfx = new boolean[fxnum+1];
skipfy = new boolean[fynum+1];


for (int i=0; i<fxnum; i++) {
//fx[i]=(int)random(6);
fx[i]=(int)random(6);
phx[i] = random(1);
skipfx[i] = random(1)<0.2;
sx[i] = random(1)<0.2?-1:1;
}
for (int i=0; i<fynum; i++) {
fy[i]=(int)random(6);
//fy[i]=6;
phy[i] = random(1);
skipfy[i] = random(1)<0.2;
sy[i] = random(1)<0.2?-1:1;
}
dox = random(1)<0.8;
doy = dox?random(1)<0.8:true;
}


void apply() {
renderer.beginDraw();
renderer.colorMode(RGB);
renderer.noStroke();
colorMode(RGB);
renderer.fill(255);
if (!this.animating) {
// buffer = createImage(renderW, renderH, ARGB);
buffer.resize(renderer.width, renderer.height);
buffer = renderer.get(0, 0, renderer.width, renderer.height);
// int s = buffer.width>buffer.height?buffer.height:buffer.width;
// depth = (int)(log(s)/log(2));
// fxnum = (int)map(knobZero, 0, 255, 0, depth);
// fynum = (int)map(knobOne, 0, 255, 0, depth);
// fx = new int[fxnum+1];
// fy = new int[fynum+1];
// sx = new int[fxnum+1];
// sy = new int[fynum+1];
//
// phx = new float[fxnum+1];
// phy = new float[fynum+1];
//
// skipfx = new boolean[fxnum+1];
// skipfy = new boolean[fynum+1];
//
//
// for (int i=0; i<fxnum; i++) {
// fx[i]=(int)random(6);
// phx[i] = random(1);
// skipfx[i] = random(1)<0.2;
// sx[i] = random(1)<0.2?-1:1;
// }
// for (int i=0; i<fynum; i++) {
// fy[i]=(int)random(6);
// phy[i] = random(1);
// skipfy[i] = random(1)<0.2;
// sy[i] = random(1)<0.2?-1:1;
// }
// dox = random(1)<0.8;
// doy = dox?random(1)<0.8:true;
// } else {
// println("ratatata");
// buffer = createImage(renderW, renderH, ARGB);
// buffer = renderer.get(0, 0, renderer.width, renderer.height);
}


float v=0;
for (int y=0; y<buffer.height; y++)
for (int x=0; x<buffer.width; x++) {
float iy = map(y, 0, buffer.height, 0, 1);

v=0;
if (doy) for (int i=0; i<fy.length; i++)
if (!skipfy[i]) v+=sy[i]*getValue(fy[i], iy, i, phy[i]);

float ry = 2*iy+v;
float y2 = (3*buffer.height+ry * buffer.height/2)%buffer.height;

float ix = map(x, 0, buffer.width, 0, 1);
v=0;
if (dox) for (int i=0; i<fx.length; i++)
if (!skipfx[i]) v+=sx[i]*getValue(fx[i], ix, i, phx[i]);


float rx = 2*ix+v;
float x2 = (3*buffer.width+rx * buffer.width/2)%buffer.width;

renderer.fill(buffer.get((int)x2, (int)y2));
renderer.rect(x, y, 1, 1);
}
renderer.endDraw();
}

float getValue(int fun, float idx, int freq, float phase) {
switch(fun) {
case 0:
return getSin(idx, freq, phase);
case 1:
return getSaw(idx, freq, phase);
case 2:
return getTriangle(idx, freq, phase);
case 3:
return getCutTriangle(idx, freq, phase);
case 4:
return getSquare(idx, freq, phase);
case 5:
return getNoise(idx, freq, phase);
default:
return getSin(idx, freq, phase);
}
}

float getNoise(float idx, int freq, float phase) {
return 2*ft[1][freq]*(noise((idx+phase)*ft[0][freq])-0.5);
}

float getSin(float idx, int freq, float phase) {
float p = ft[0][freq];
return ft[1][freq] * sin(idx*TWO_PI*p+phase*TWO_PI);
}

float getSaw(float idx, int freq, float phase) {
float p = ft[0][freq];
float rp = 2.0*ft[1][freq];
float p2 = p*((idx+phase+ft[1][freq])%1.0);
return rp*(p2-floor(p2)-0.5);
}

float getSquare(float idx, int freq, float phase) {
float p = ft[0][freq];
float rp = ft[1][freq];
return (((idx*p)+phase)%1.0)<0.5?rp:-rp;
}

float getTriangle(float idx, int freq, float phase) {
return 2*abs(getSaw(idx, freq, phase+0.5*ft[1][freq]))-ft[1][freq];
}

float getCutTriangle(float idx, int freq, float phase) {
return constrain(getTriangle(idx, freq, phase), -ft[1][freq+1], ft[1][freq+1]);
}
}

+ 250
- 0
WZIP.pde View File

class WZIP extends Shader {


final float sqrt05 = sqrt(0.5);

float[] raw, raw1, raw2, raw3;
float[] in, w, out;
float[] in1, in2, in3, out1, out2, out3;
int n, n2, s;
float scalingfactorin, scalingfactorout;

PImage img;
String sessionid;



WZIP() {

name = "fxWZIP";/*
params.add(new Param ("scale", 0, 1000));
params.add(new Param ("factor1", 0, 1));
params.add(new Param ("factor2", 0, 1));
params.add(new Param ("hsb", 2));
params.add(new Param ("mode", 2));
*/

sessionid = hex((int)random(0xffff), 4);
img = createImage(renderer.width, renderer.height, ARGB);
img = renderer.get(0, 0, renderer.width, renderer.height);



// printOption();
// printScale();
}

/*
float inc1, inc2;
void animate() {
inc1+=.03;
inc2+=.04;
//gui.brickP5.getController("knobZero-"+str(brick)).setValue( map(sin(inc1), -1, 1, 0, 255));
//gui.brickP5.getController("knobOne-"+str(brick)).setValue(map(cos(inc2), -1, 1, 0, 255));
if (random(1) > .99) {
for (int i = 0; i < params.size(); i++)
params.get(i).randomize();
}
}
*/
void apply() {
// img = createImage(renderer.width, renderer.height, ARGB);
img.resize(renderer.width, renderer.height);
img = renderer.get(0, 0, renderer.width, renderer.height);

s = img.width*img.height;
raw = new float[s*3];
raw1 = new float[s];
raw2 = new float[s];
raw3 = new float[s];
renderer.beginDraw();
renderer.background(0);
renderer.noStroke();
if (boolean((int)params.get(3).value)) {
renderer.colorMode(HSB, 255);
colorMode(HSB, 255);
} else {
renderer.colorMode(RGB, 255);
colorMode(RGB, 255);
}

scalingfactorin = map(params.get(1).value, 0, 1, 0, params.get(0).value);
scalingfactorout = map(params.get(2).value, 0, 1, 0, params.get(0).value);
int iter=0;
int iter2 = 0;
for (int y=0; y<img.height; y++) {
for (int x=0; x<img.width; x++) {
color c = img.get(x, y);
float r, g, b;
if (boolean((int)params.get(3).value)) {
r = hue(c)>127?hue(c)-256:hue(c);
g = saturation(c)>127?saturation(c)-256:saturation(c);
b = brightness(c)>127?brightness(c)-256:brightness(c);
} else {
r = red(c)>127?red(c)-256:red(c);
g = green(c)>127?green(c)-256:green(c);
b = blue(c)>127?blue(c)-256:blue(c);
}
raw[iter++] = r;
raw[iter++] = g;
raw[iter++] = b;
raw1[iter2] = r;
raw2[iter2] = g;
raw3[iter2] = b;
iter2++;
}
}

n = (int)pow(2, ceil(log(s*3)/log(2)));
n2 = (int)pow(2, ceil(log(s)/log(2)));

in = new float[n];
w = new float[n];
out = new float[n];
out1 = new float[n2];
out2 = new float[n2];
out3 = new float[n2];
in1 = new float[n2];
in2 = new float[n2];
in3 = new float[n2];

arrayCopy(raw, 0, in, 0, raw.length);
for (int i=raw.length; i<n; i++) in[i] = raw[raw.length-1];

arrayCopy(raw1, 0, in1, 0, s);
arrayCopy(raw2, 0, in2, 0, s);
arrayCopy(raw3, 0, in3, 0, s);

for (int i=s; i<n2; i++) {
in1[i] = raw1[s-1];
in2[i] = raw2[s-1];
in3[i] = raw3[s-1];
}
if (boolean((int)params.get(4).value)) option1();
else option2();
renderer.colorMode(RGB);
colorMode(RGB);
renderer.endDraw();
}
// void printOption() {
// String str1, str2;
// if (do_hsb) {
// str1 = "HSBHSBHSB...";
// str2 = "HHH...SSS...BBB...";
// } else {
// str1 = "RGBRGBRGB...";
// str2 = "RRR...GGG...BBB...";
// }
// if (option1) println("channels combined: " + str1);
// else println("channels separated: " + str2);
// }
//
// void printScale() {
// println("Scale: 0.."+sc);
// }

float clamp(float c) {
return(abs(c<0?256+c:c)%255.0);
}
void option2() {
wtrafo(in1, n2);
wbtrafo(out1, n2);

wtrafo(in2, n2);
wbtrafo(out2, n2);

wtrafo(in3, n2);
wbtrafo(out3, n2);

for (int i=0; i<s; i++) {
float r = clamp(out1[i]);
float g = clamp(out2[i]);
float b = clamp(out3[i]);
renderer.fill(r, g, b);
renderer.rect(i%img.width, i/img.width, 1, 1);
}
}
void option1() {
wtrafo(in, n);
wbtrafo(out, n);

float r=0, g=0, b=0;
int state = 0;

for (int i=0; i<raw.length; i++) {
float c = clamp(out[i]);
switch(state) {
case 0:
r = c;
break;
case 1:
g = c;
break;
case 2:
b = c;
break;
default:
{
r = c;
renderer.fill(r, g, b);
renderer.rect(floor(i/3.0)%img.width, floor(i/3.0)/img.width, 1, 1);
state = 0;
}
}
state++;
}
}




void wbtrafo(float[] y, int n) {
float[] d = new float[n];
d[n-2] = w[n-1];
int b1 = n-4;
int b2 = n-2;
int a=1;
while (a<n/2) {
for (int i=0; i<a; i++) {
d[2*i+b1]=(d[i+b2]+w[i+b2])*sqrt05;
d[2*i+1+b1]=(d[i+b2]-w[i+b2])*sqrt05;
}
b2=b1;
b1=b1-4*a;
a*=2;
}

for (int i=0; i<a; i++) {
y[2*i]=(d[i]+w[i])*sqrt05;
y[2*i+1]=(d[i]-w[i])*sqrt05;
}

for (int i=0; i<n; i++) y[i] *= scalingfactorout;
}

void wtrafo(float[] y, int n) {
float[] d = new float[n];
int a = n/2;
for (int i=0; i<a; i++) {
w[i] = (y[2*i]-y[2*i+1])*sqrt05;
d[i] = (y[2*i]+y[2*i+1])*sqrt05;
}
int b1 = 0;
int b2 = a;
a/=2;
while (a>0) {
for (int i=0; i<a; i++) {
w[i+b2]=(d[2*i+b1]-d[2*i+1+b1])*sqrt05;
d[i+b2]=(d[2*i+b1]+d[2*i+1+b1])*sqrt05;
}
b1=b2;
b2=b2+a;
a/=2;
}
w[b2] = d[b1];

for (int i=0; i<n-1; i++) w[i] = (int)(w[i]/scalingfactorin);
if (w[n-1]>0) w[n-1] = (int)(w[n-1]/scalingfactorin+0.5);
else w[n-1] = (int)(w[n-1]/scalingfactorin-0.5);
}
}

+ 800
- 0
colorspaces.pde View File

//from tomasz sulej's FM effect

final static int COLORSPACES = 16;

final static int OHTA = 0;
// RGB == 1; defined in processing
final static int CMY = 2;
// HSB == 3; defined in processing
final static int XYZ = 4;
final static int YXY = 5;
final static int HCL = 6;
final static int LUV = 7;
final static int LAB = 8;
final static int HWB = 9;
final static int RGGBG = 10;
final static int YPbPr = 11;
final static int YCbCr = 12;
final static int YDbDr = 13;
final static int GS = 14;
final static int YUV = 15;

// name
String getColorspaceName(int cs) {
switch(cs) {
case OHTA:
return "OHTA";
case CMY:
return "CMY";
case XYZ:
return "XYZ";
case YXY:
return "YXY";
case HCL:
return "HCL";
case LUV:
return "LUV";
case LAB:
return "LAB";
case HWB:
return "HWB";
case HSB:
return "HSB";
case RGGBG:
return "R-GGB-G";
case YPbPr:
return "YPbPr";
case YCbCr:
return "YCbCr";
case YDbDr:
return "YDbDr";
case GS:
return "Greyscale";
case YUV:
return "YUV";
default:
return "RGB";
}
}

// colorspace converters
color fromColorspace(color c, int cs) {
switch(cs) {
case OHTA:
return fromOHTA(c);
case CMY:
return fromCMY(c);
case XYZ:
return fromXYZ(c);
case YXY:
return fromYXY(c);
case HCL:
return fromHCL(c);
case LUV:
return fromLUV(c);
case LAB:
return fromLAB(c);
case HWB:
return fromHWB(c);
case HSB:
return fromHSB(c);
case RGGBG:
return fromRGGBG(c);
case YPbPr:
return fromYPbPr(c);
case YCbCr:
return fromYCbCr(c);
case YDbDr:
return fromYDbDr(c);
case GS:
return tofromGS(c);
case YUV:
return fromYUV(c);
default:
return c;
}
}

color toColorspace(color c, int cs) {
switch(cs) {
case OHTA:
return toOHTA(c);
case CMY:
return toCMY(c);
case XYZ:
return toXYZ(c);
case YXY:
return toYXY(c);
case HCL:
return toHCL(c);
case LUV:
return toLUV(c);
case LAB:
return toLAB(c);
case HWB:
return toHWB(c);
case HSB:
return toHSB(c);
case RGGBG:
return toRGGBG(c);
case YPbPr:
return toYPbPr(c);
case YCbCr:
return toYCbCr(c);
case YDbDr:
return toYDbDr(c);
case YUV:
return toYUV(c);
case GS:
return tofromGS(c);
default:
return c;
}
}

// Colorspace converters

final int getR(color c) {
return (c & 0xff0000) >> 16;
}
final int getG(color c) {
return (c & 0xff00) >> 8;
}
final int getB(color c) {
return c & 0xff;
}

final int getLuma(color c) {
return constrain((int)(0.2126*getR(c)+0.7152*getG(c)+0.0722*getB(c)), 0, 255);
}

int getChannel(color c, int ch) {
switch(ch) {
case 0 :
return getR(c);
case 1 :
return getG(c);
case 2 :
return getB(c);
default:
return 0;
}
}

// normalized versions
final float getNR(color c) {
return r255[(c & 0xff0000) >> 16];
}
final float getNG(color c) {
return r255[(c & 0xff00) >> 8];
}
final float getNB(color c) {
return r255[c & 0xff];
}
final float getNLuma(color c) {
return r255[getLuma(c)];
}

color blendRGB(color c, int r, int g, int b) {
return (c & 0xff000000) | (constrain(r, 0, 255) << 16) | (constrain(g, 0, 255) << 8 ) | constrain(b, 0, 255);
}

color blendRGB(color c, float r, float g, float b) {
return blendRGB(c, (int)(r*255), (int)(g*255), (int)(b*255));
}

/**************
* Greyscale
**************/

color tofromGS(color c) {
int l = getLuma(c);
return blendRGB(c, l, l, l);
}

/**************
* YUV
**************/

final static float Umax = 0.436 * 255.0;
final static float Vmax = 0.615 * 255.0;

color toYUV(color c) {
int R = getR(c);
int G = getG(c);
int B = getB(c);
int Y = (int)( 0.299*R+0.587*G+0.114*B);
int U = (int)map(-0.14713*R-0.28886*G+0.436*B,-Umax,Umax,0,255);
int V = (int)map(0.615*R-0.51499*G-0.10001*B,-Vmax,Vmax,0,255);

return blendRGB(c, Y, U, V);
}

color fromYUV(color c) {
int Y = getR(c);
float U = map(getG(c),0,255,-Umax,Umax);
float V = map(getB(c),0,255,-Vmax,Vmax);
int R = (int)(Y + 1.13983*V);
int G = (int)(Y - 0.39465*U - 0.58060*V);
int B = (int)(Y + 2.03211*U);
return blendRGB(c, R, G, B);
}

/**************
* YDbDr
**************/

color toYDbDr(color c) {
int R = getR(c);
int G = getG(c);
int B = getB(c);
int Y = (int)( 0.299*R+0.587*G+0.114*B);
int Db = (int)(127.5+(-0.450*R-0.883*G+1.333*B)/2.666);
int Dr = (int)(127.5+(-1.333*R+1.116*G+0.217*B)/2.666);

return blendRGB(c, Y, Db, Dr);
}

color fromYDbDr(color c) {
int Y = getR(c);
float Db = (getG(c)-127.5)*2.666;
float Dr = (getB(c)-127.5)*2.666;
int R = (int)(Y + 9.2303716147657e-05*Db-0.52591263066186533*Dr);
int G = (int)(Y - 0.12913289889050927*Db+0.26789932820759876*Dr);
int B = (int)(Y + 0.66467905997895482*Db-7.9202543533108e-05*Dr);
return blendRGB(c, R, G, B);
}

/**************
* YCbCr
**************/

color toYCbCr(color c) {
int R = getR(c);
int G = getG(c);
int B = getB(c);
int Y = (int)( 0.2988390*R+0.5868110*G+0.1143500*B);
int Cb = (int)(-0.168736*R-0.3312640*G+0.5000000*B+127.5);
int Cr = (int)( 0.5000000*R-0.4186880*G-0.0813120*B+127.5);

return blendRGB(c, Y, Cb, Cr);
}

color fromYCbCr(color c) {
int Y = getR(c);
float Cb = getG(c) - 127.5;
float Cr = getB(c) - 127.5;
int R = (int)(Y + 1.402*Cr)+1; // some fix
int G = (int)(Y-0.344136*Cb-0.714136*Cr);
int B = (int)(Y+1.772000*Cb)+1; // some fix
return blendRGB(c, R, G, B);
}

/**************
* YPbPr
**************/

color toYPbPr(color c) {
int R = getR(c);
int B = getB(c);
int Y = getLuma(c);
int Pb = B - Y;
int Pr = R - Y;
if(Pb<0) Pb+=256;
if(Pr<0) Pr+=256;
return blendRGB(c, Y, Pb, Pr);
}

color fromYPbPr(color c) {
int Y = getR(c);
int B = getG(c) + Y;
int R = getB(c) + Y;
if(R>255) R-=256;
if(B>255) B-=256;
int G = (int)((Y-0.2126*R-0.0722*B)/0.7152);
return blendRGB(c, R, G, B);
}


/**************
* R-G,G,B-G
**************/

color toRGGBG(color c) {
int G = getG(c);
int R = getR(c)-G;
int B = getB(c)-G;
if(R<0) R+=256;
if(B<0) B+=256;
return blendRGB(c, R, G, B);
}

color fromRGGBG(color c) {
int G = getG(c);
int R = getR(c)+G;
int B = getB(c)+G;
if(R>255) R-=256;
if(B>255) B-=256;
return blendRGB(c, R, G, B);
}

/**************
* HWB
**************/

color toHSB(color c) {
int R = getR(c);
int G = getG(c);
int B = getB(c);

int _min = min(R, G, B);
int _max = max(R, G, B);
float delta = _max-_min;
float saturation = delta/_max;
float brightness = r255[_max];
if (delta == 0.0) return blendRGB(c, 0.0, saturation, brightness);
float hue = 0;
if (R == _max) hue = (G-B)/delta;
else if (G == _max) hue = 2.0 + (B-R)/delta;
else hue = 4.0 + (R-G)/delta;
hue /= 6.0;
if (hue < 0.0) hue += 1.0;
return blendRGB(c, hue, saturation, brightness);
}

color fromHSB(color c) {
float S = getNG(c);
float B = getNB(c);
if (S == 0.0) return blendRGB(c, B, B, B);

float h = 6.0 * getNR(c);
float f = h-floor(h);
float p = B*(1.0-S);
float q = B*(1.0-S*f);
float t = B*(1.0-(S*(1.0-f)));

float r, g, b;
switch((int)h) {
case 1:
r=q;
g=B;
b=p;
break;
case 2:
r=p;
g=B;
b=t;
break;
case 3:
r=p;
g=q;
b=B;
break;
case 4:
r=t;
g=p;
b=B;
break;
case 5:
r=B;
g=p;
b=q;
break;
default:
r=B;
g=t;
b=p;
break;
}
return blendRGB(c, r, g, b);
}



/**************
* HWB
**************/

color toHWB(color c) {
int R = getR(c);
int G = getG(c);
int B = getB(c);

int w = min(R, G, B);
int v = max(R, G, B);

int hue;
if (v == w) hue = 255;
else {
float f = ((R == w) ? G-B : ((G == w) ? B-R : R-G));
float p = (R == w) ? 3.0 : ((G == w) ? 5.0 : 1.0);
hue = (int)map((p-f/(v-w))/6.0, 0, 1, 0, 254);
}
return blendRGB(c, hue, w, 255-v);
}

color fromHWB(color c) {
int H = getR(c);
int B = 255-getB(c);
if (H == 255) return blendRGB(c, B, B, B);
else {
float hue = map(H, 0, 254, 0, 6);
float v = r255[B];
float whiteness = getNG(c);
int i = (int)floor(hue);
float f = hue-i;
if ((i&0x01)!= 0) f=1.0-f;
float n = whiteness+f*(v-whiteness);
float r, g, b;
switch(i) {
case 1:
r=n;
g=v;
b=whiteness;
break;
case 2:
r=whiteness;
g=v;
b=n;
break;
case 3:
r=whiteness;
g=n;
b=v;
break;
case 4:
r=n;
g=whiteness;
b=v;
break;
case 5:
r=v;
g=whiteness;
b=n;
break;
default:
r=v;
g=n;
b=whiteness;
break;
}
return blendRGB(c, r, g, b);
}
}

/**************
* Lab
**************/

final static float D65X=0.950456;
final static float D65Y=1.0;
final static float D65Z=1.088754;
final static float CIEEpsilon=(216.0/24389.0);
final static float CIEK=(24389.0/27.0);
final static float CIEK2epsilon = CIEK * CIEEpsilon;
final static float D65FX_4 = 4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z);
final static float D65FY_9 = 9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z);
final static float RANGE_X = 100.0 * (0.4124+0.3576+0.1805);
final static float RANGE_Y = 100.0;
final static float RANGE_Z = 100.0 * (0.0193+0.1192+0.9505);
final static float mepsilon = 1.0e-10;
final static float corrratio = 1.0/2.4;
final static float One_Third = 1.0/3.0;
final static float one_hsixteen = 1.0/116.0;

color toLAB(color c) {
PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
xyz.div(100.0);
xyz.x /= D65X;
xyz.y /= D65Y;
xyz.z /= D65Z;
float x, y, z;

if (xyz.x > CIEEpsilon) {
x = pow(xyz.x, One_Third);
} else {
x= (CIEK*xyz.x+16.0)*one_hsixteen;
}

if (xyz.y > CIEEpsilon) {
y = pow(xyz.y, One_Third);
} else {
y = (CIEK*xyz.y+16.0)*one_hsixteen;
}

if (xyz.z > CIEEpsilon) {
z = pow(xyz.z, One_Third);
} else {
z = (CIEK*xyz.z+16.0)*one_hsixteen;
}

float L = 255.0*(((116.0*y)-16.0)*0.01);
float a = 255.0*(0.5*(x-y)+0.5);
float b = 255.0*(0.5*(y-z)+0.5);

return blendRGB(c, round(L), round(a), round(b));
}

color fromLAB(color c) {
float L = 100*getNR(c);
float a = getNG(c)-0.5;
float b = getNB(c)-0.5;

float y = (L+16.0)*one_hsixteen;
float x = y+a;
float z = y-b;

float xxx=x*x*x;
if (xxx>CIEEpsilon) {
x = xxx;
} else {
x = (116.0*x-16.0)/CIEK;
}

float yyy=y*y*y;
if (yyy>CIEEpsilon) {
y = yyy;
} else {
y = L/CIEK;
}

float zzz=z*z*z;
if (zzz>CIEEpsilon) {
z = zzz;
} else {
z = (116.0*z-16.0)/CIEK;
}

return _fromXYZ(c, RANGE_X*x, RANGE_Y*y, RANGE_Z*z);
}

/**************
* Luv
**************/

final float PerceptibleReciprocal(float x) {
float sgn = x < 0.0 ? -1.0 : 1.0;
if ((sgn * x) >= mepsilon) return (1.0 / x);
return (sgn/mepsilon);
}

color toLUV(color c) {
PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
xyz.div(100.0);
float d = xyz.y; // / D65Y;
float L;
if (d > CIEEpsilon) L = 116.0*pow(d, One_Third)-16.0;
else L = CIEK * d;
float alpha = PerceptibleReciprocal(xyz.x + 15.0 * xyz.y + 3.0 * xyz.z);
float L13 = 13.0 * L;
float u = L13 * ((4.0 * alpha * xyz.x)-D65FX_4);
float v = L13 * ((9.0 * alpha * xyz.y)-D65FY_9);
L /= 100.0;
u=(u+134.0)/354.0;
v=(v+140.0)/262.0;
return blendRGB(c, round(L*255), round(u*255), round(v*255));
}

color fromLUV(color c) {
float L = 100.0*getNR(c);
float u = 354.0*getNG(c)-134.0;
float v = 262.0*getNB(c)-140.0;
float X, Y, Z;
if (L > CIEK2epsilon) Y = pow((L+16.0)*one_hsixteen, 3.0);
else Y = L/CIEK;
float L13 = 13.0*L;
float L52 = 52.0*L;
float Y5 = 5.0*Y;
float L13u = L52/(u+L13*D65FX_4);
X=((Y*((39.0*L/(v+L13*D65FY_9))-5.0))+Y5)/((((L13u)-1.0)/3.0)+One_Third);
Z=(X*(((L13u)-1.0)/3.0))-Y5;
return _fromXYZ(c, 100*X, 100*Y, 100*Z);
}

/**************
* HCL
**************/

color toHCL(color c) {
float r = getNR(c);
float g = getNG(c);
float b = getNB(c);
float max = max(r, max(g, b));
float chr = max - min(r, min(g, b));
float h = 0.0;
if ( chr != 0) {
if (r == max) {
h = ((g-b)/chr+6.0) % 6.0;
} else if (g == max) {
h = (b-r)/chr + 2.0;
} else {
h = (r-g)/chr + 4.0;
}
}
return blendRGB(c, round((h/6.0)*255), round(chr*255), round(255*(0.298839*r+0.586811*g+0.114350*b)));
}

color fromHCL(color c) {
float h = 6.0*getNR(c);
float chr = getNG(c);
float l = getNB(c);
float x = chr*(1.0-abs((h%2.0)-1.0));
float r = 0.0;
float g = 0.0;
float b = 0.0;
if ((0.0 <= h) && (h < 1.0)) {
r=chr;
g=x;
} else if ((1.0 <= h) && (h < 2.0)) {
r=x;
g=chr;
} else if ((2.0 <= h) && (h < 3.0)) {
g=chr;
b=x;
} else if ((3.0 <= h) && (h < 4.0)) {
g=x;
b=chr;
} else if ((4.0 <= h) && (h < 5.0)) {
r=x;
b=chr;
} else {//if ((5.0 <= h) && (h < 6.0)) {
r=chr;
b=x;
}
float m = l - (0.298839*r+0.586811*g+0.114350*b);
return blendRGB(c, round(255*(r+m)), round(255*(g+m)), round(255*(b+m)));
}

/**************
* Yxy
**************/

color toYXY(color c) {
PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
float sum = xyz.x + xyz.y + xyz.z;
float x = xyz.x > 0 ? xyz.x / sum : 0.0;
float y = xyz.y > 0 ? xyz.y / sum : 0.0;
return blendRGB(c,
(int)map(xyz.y, 0, RANGE_Y, 0, 255),
(int)map(x, 0.0, 1.0, 0, 255),
(int)map(y, 0.0, 1.0, 0, 255));
}

color fromYXY(color c) {
float Y = map(getR(c), 0, 255, 0, RANGE_Y);
float x = map(getG(c), 0, 255, 0, 1.0);
float y = map(getB(c), 0, 255, 0, 1.0);
float divy = Y / (y>0 ? y : 1.0e-6);

return _fromXYZ(c, x * divy, Y, (1-x-y)*divy);
}

/**************
* XYZ
**************/

// FIXME: range from 0 to 1
float correctionxyz(float n) {
return (n > 0.04045 ? pow((n + 0.055) / 1.055, 2.4) : n / 12.92) * 100.0;
}

PVector _toXYZ(float rr, float gg, float bb) {
float r = correctionxyz(rr);
float g = correctionxyz(gg);
float b = correctionxyz(bb);
return new PVector(r * 0.4124 + g * 0.3576 + b * 0.1805,
r * 0.2126 + g * 0.7152 + b * 0.0722,
r * 0.0193 + g * 0.1192 + b * 0.9505);
}

color toXYZ(color c) {
PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
return blendRGB(c,
(int)map(xyz.x, 0, RANGE_X, 0, 255),
(int)map(xyz.y, 0, RANGE_Y, 0, 255),
(int)map(xyz.z, 0, RANGE_Z, 0, 255));
}

float recorrectionxyz(float n) {
return n > 0.0031308 ? 1.055 * pow(n, corrratio) - 0.055 : 12.92 * n;
}

// FIXME: range from 0 to 1
color _fromXYZ(color c, float xx, float yy, float zz) {
float x = xx/100.0;
float y = yy/100.0;
float z = zz/100.0;

int r = round(255.0*recorrectionxyz(x * 3.2406 + y * -1.5372 + z * -0.4986));
int g = round(255.0*recorrectionxyz(x * -0.9689 + y * 1.8758 + z * 0.0415));
int b = round(255.0*recorrectionxyz(x * 0.0557 + y * -0.2040 + z * 1.0570));

return blendRGB(c, r, g, b);
}

color fromXYZ(color c) {
float x = map(getR(c), 0, 255, 0, RANGE_X);
float y = map(getG(c), 0, 255, 0, RANGE_Y);
float z = map(getB(c), 0, 255, 0, RANGE_Z);

return _fromXYZ(c, x, y, z);
}

/**************
* CMY
**************/

color toCMY(color c) {
return blendRGB(c, 255-getR(c), 255-getG(c), 255-getB(c));
}

color fromCMY(color c) {
return toCMY(c);
}

/**************
* OHTA
**************/

color fromOHTA(color c) {
int I1 = getR(c);
float I2 = map(getG(c), 0, 255, -127.5, 127.5);
float I3 = map(getB(c), 0, 255, -127.5, 127.5);

int R = (int)(I1+1.00000*I2-0.66668*I3);
int G = (int)(I1+1.33333*I3);
int B = (int)(I1-1.00000*I2-0.66668*I3);

return blendRGB(c, R, G, B);
}

color toOHTA(color c) {
int R = getR(c);
int G = getG(c);
int B = getB(c);

int I1 = (int)(0.33333*R+0.33334*G+0.33333*B);
int I2 = (int)map(0.5*(R-B), -127.5, 127.5, 0, 255);
int I3 = (int)map(-0.25000*R+0.50000*G-0.25000*B, -127.5, 127.5, 0, 255);

return blendRGB(c, I1, I2, I3);
}

////
// 1/n table for n=0..255 - to speed up color conversions things
final static float[] r255 = {
0.0, 0.003921569, 0.007843138, 0.011764706, 0.015686275, 0.019607844, 0.023529412, 0.02745098, 0.03137255, 0.03529412, 0.039215688,
0.043137256, 0.047058824, 0.050980393, 0.05490196, 0.05882353, 0.0627451, 0.06666667, 0.07058824, 0.07450981, 0.078431375, 0.08235294,
0.08627451, 0.09019608, 0.09411765, 0.09803922, 0.101960786, 0.105882354, 0.10980392, 0.11372549, 0.11764706, 0.12156863, 0.1254902,
0.12941177, 0.13333334, 0.13725491, 0.14117648, 0.14509805, 0.14901961, 0.15294118, 0.15686275, 0.16078432, 0.16470589, 0.16862746,
0.17254902, 0.1764706, 0.18039216, 0.18431373, 0.1882353, 0.19215687, 0.19607843, 0.2, 0.20392157, 0.20784314, 0.21176471, 0.21568628,
0.21960784, 0.22352941, 0.22745098, 0.23137255, 0.23529412, 0.23921569, 0.24313726, 0.24705882, 0.2509804, 0.25490198, 0.25882354,
0.2627451, 0.26666668, 0.27058825, 0.27450982, 0.2784314, 0.28235295, 0.28627452, 0.2901961, 0.29411766, 0.29803923, 0.3019608, 0.30588236,
0.30980393, 0.3137255, 0.31764707, 0.32156864, 0.3254902, 0.32941177, 0.33333334, 0.3372549, 0.34117648, 0.34509805, 0.34901962, 0.3529412,
0.35686275, 0.36078432, 0.3647059, 0.36862746, 0.37254903, 0.3764706, 0.38039216, 0.38431373, 0.3882353, 0.39215687, 0.39607844, 0.4,
0.40392157, 0.40784314, 0.4117647, 0.41568628, 0.41960785, 0.42352942, 0.42745098, 0.43137255, 0.43529412, 0.4392157, 0.44313726,
0.44705883, 0.4509804, 0.45490196, 0.45882353, 0.4627451, 0.46666667, 0.47058824, 0.4745098, 0.47843137, 0.48235294, 0.4862745, 0.49019608,
0.49411765, 0.49803922, 0.5019608, 0.5058824, 0.50980395, 0.5137255, 0.5176471, 0.52156866, 0.5254902, 0.5294118, 0.53333336, 0.5372549,
0.5411765, 0.54509807, 0.54901963, 0.5529412, 0.5568628, 0.56078434, 0.5647059, 0.5686275, 0.57254905, 0.5764706, 0.5803922, 0.58431375,
0.5882353, 0.5921569, 0.59607846, 0.6, 0.6039216, 0.60784316, 0.6117647, 0.6156863, 0.61960787, 0.62352943, 0.627451, 0.6313726, 0.63529414,
0.6392157, 0.6431373, 0.64705884, 0.6509804, 0.654902, 0.65882355, 0.6627451, 0.6666667, 0.67058825, 0.6745098, 0.6784314, 0.68235296,
0.6862745, 0.6901961, 0.69411767, 0.69803923, 0.7019608, 0.7058824, 0.70980394, 0.7137255, 0.7176471, 0.72156864, 0.7254902, 0.7294118,
0.73333335, 0.7372549, 0.7411765, 0.74509805, 0.7490196, 0.7529412, 0.75686276, 0.7607843, 0.7647059, 0.76862746, 0.77254903, 0.7764706,
0.78039217, 0.78431374, 0.7882353, 0.7921569, 0.79607844, 0.8, 0.8039216, 0.80784315, 0.8117647, 0.8156863, 0.81960785, 0.8235294, 0.827451,
0.83137256, 0.8352941, 0.8392157, 0.84313726, 0.84705883, 0.8509804, 0.85490197, 0.85882354, 0.8627451, 0.8666667, 0.87058824, 0.8745098,
0.8784314, 0.88235295, 0.8862745, 0.8901961, 0.89411765, 0.8980392, 0.9019608, 0.90588236, 0.9098039, 0.9137255, 0.91764706, 0.92156863,
0.9254902, 0.92941177, 0.93333334, 0.9372549, 0.9411765, 0.94509804, 0.9490196, 0.9529412, 0.95686275, 0.9607843, 0.9647059, 0.96862745,
0.972549, 0.9764706, 0.98039216, 0.9843137, 0.9882353, 0.99215686, 0.99607843, 1.0
};

BIN
data/0.mp4 View File


BIN
data/0.png View File


BIN
data/1.png View File


BIN
data/mask.png View File


BIN
data/potrace View File


+ 2
- 0
data/saves.sav View File

//globals
uptime = 116617879

+ 47
- 0
ffmpeg.txt View File

ffmpeg version 3.4.8-0ubuntu0.2 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
configuration: --prefix=/usr --extra-version=0ubuntu0.2 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
WARNING: library configuration mismatch
avcodec configuration: --prefix=/usr --extra-version=0ubuntu0.2 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared --enable-version3 --disable-doc --disable-programs --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libtesseract --enable-libvo_amrwbenc
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Input #0, rawvideo, from 'pipe:':
Duration: N/A, start: 0.000000, bitrate: 88957 kb/s
Stream #0:0: Video: rawvideo (RGB[24] / 0x18424752), rgb24, 468x264, 88957 kb/s, 30 tbr, 30 tbn, 30 tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
[swscaler @ 0x562d1e168ac0] Warning: data is not aligned! This can lead to a speed loss
[libx264 @ 0x562d1e156d20] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x562d1e156d20] profile High 4:4:4 Predictive, level 2.1, 4:2:0 8-bit
[libx264 @ 0x562d1e156d20] 264 - core 152 r2854 e9a5903 - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x1:0x111 me=hex subme=7 psy=0 mixed_ref=1 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=8 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, mp4, to '/media/giers/projekte/Gerkzeuk/gerkzeuk2/gerkzeuk2_p5_0001/data/videos/116618113.mp4':
Metadata:
comment : Made with Video Export for Processing - https://git.io/vAXLk
encoder : Lavf57.83.100
Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 468x264, q=-1--1, 30 fps, 15360 tbn, 30 tbc
Metadata:
encoder : Lavc57.107.100 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
frame= 17 fps=0.0 q=0.0 size= 256kB time=00:00:00.23 bitrate=8986.9kbits/s speed=0.438x frame= 33 fps= 32 q=0.0 size= 1280kB time=00:00:00.76 bitrate=13676.4kbits/s speed=0.733x frame= 49 fps= 31 q=0.0 size= 1792kB time=00:00:01.30 bitrate=11292.1kbits/s speed=0.824x frame= 53 fps= 30 q=-1.0 Lsize= 2709kB time=00:00:01.73 bitrate=12804.1kbits/s speed=0.973x
video:2708kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.041469%
[libx264 @ 0x562d1e156d20] frame I:2 Avg QP: 0.00 size: 80171
[libx264 @ 0x562d1e156d20] frame P:51 Avg QP: 0.00 size: 51222
[libx264 @ 0x562d1e156d20] mb I I16..4: 26.1% 0.0% 73.9%
[libx264 @ 0x562d1e156d20] mb P I16..4: 13.7% 0.0% 14.2% P16..4: 20.1% 18.3% 13.0% 0.0% 0.0% skip:20.7%
[libx264 @ 0x562d1e156d20] 8x8 transform intra:0.0% inter:55.0%
[libx264 @ 0x562d1e156d20] coded y,uvDC,uvAC intra: 93.2% 96.6% 96.4% inter: 68.7% 70.2% 70.1%
[libx264 @ 0x562d1e156d20] i16 v,h,dc,p: 85% 14% 1% 0%
[libx264 @ 0x562d1e156d20] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 62% 22% 3% 2% 2% 2% 2% 3% 2%
[libx264 @ 0x562d1e156d20] i8c dc,h,v,p: 4% 27% 69% 0%
[libx264 @ 0x562d1e156d20] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x562d1e156d20] ref P L0: 62.1% 11.1% 17.6% 9.3%
[libx264 @ 0x562d1e156d20] kb/s:12555.43
Exiting normally, received signal 15.

+ 48
- 0
fx.pde View File

class FX {
//img in and out
Shader shader;
String[] params; // IS THIS NECESSARY? I DOUBT IT
FX(Shader shader_) {
shader = shader_;
}
}

FXManager fxManager = new FXManager();

class FXManager {
ArrayList<FX> fxList = new ArrayList<FX>();

void addFx(Shader shader) {
this.fxList.add(new FX(shader));
println("Added " + shader + " to fxList at spot. List length: " + this.fxList.size());
}

void addFx(Shader shader, int pos) {
fxList.add(new FX(shader));
swapFx(this.fxList.size(), pos);
println("Added " + shader + " to fxList at spot. List length: " + this.fxList.size());
}


void swapFx(int pos1, int pos2) {
if (pos1 >= 0 && pos2 < this.fxList.size()) Collections.swap(fxList, pos1, pos2);
}

void removeFx(int pos) {
if (pos >= 0 && this.fxList.size() > pos) this.fxList.remove(pos);
}

void run(boolean animate, boolean apply) {
for (int i = 0; i < fxManager.fxList.size(); i++) {
if (animate) {
for (int j = 0; j < this.fxList.get(i).shader.params.size(); j++) {
if (this.fxList.get(i).shader.params.get(j).animating) {
this.fxList.get(i).shader.params.get(j).animate();
}
}
}
if (apply) this.fxList.get(i).shader.apply();
if (i > maxFx) break;
}
}
}

+ 155
- 0
mangler2_0001.pde View File

import drop.*;
import test.*;

import java.util.*;
import processing.net.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import processing.video.*;
import com.hamoid.*;

VideoExport videoExport;


boolean greenBackground = false; //else: black
boolean roundMask = false; // show a circle
boolean drawGUI = true; //draws fx-informations
int mode = 1; //0: webcam, 1: image
boolean harvester = true;
int maxFx = 5; //possible amount of effect layers

int frameRate = 30;
int fpm = frameRate * 60;
int bpm = 128;

SDrop drop;
PImage source;
PGraphics renderer;
PImage viewport;
SourceManager sourceManager;


PImage roundMaskImage;

PGraphics roundMaskGraphics;


String frameName; //to save frame as image
float uptime; //logs how many frames this software has rendered before (inaccurate, it's actually way, way more)
boolean recording; //save every frame?
int renderSize = 500; //px

String[] saveData;
int w, h;




void setup() {
size(640, 800);
w = width;
h = height;
surface.setResizable(true);
frameRate(frameRate);
noSmooth(); //saves resources but makes sum look shiddy
drop = new SDrop(this);
saveData = loadStrings(dataPath("saves.sav"));
println("Loading Savefile...");
for (int i = 0; i < saveData.length; i ++) {
float[] temp;
if (saveData[i].contains("uptime")) {
temp = float(split(saveData[i], " = "));
println("Uptime: " + temp[1]);
uptime = temp[1];
}
}
fallbackImage = loadImage(dataPath("0.png"));
/*
String[] cameras = Capture.list();
if (cameras == null || cameras.length == 0) {
println(cameras == null ? "Failed to retrieve the list of available cameras." : "There are no cameras available for capture.");
if (mode == 0) {
println("Switching to image mode");
mode = 1;
}
} else {
println("Available cameras:");
printArray(cameras);
cam = new Capture(this, cameras[0]);
cam.start();
}
*/

composiorServer = new Server(this, port); // 10002

renderer = createGraphics(width, height);
viewport = createImage(renderer.width, renderer.height, ARGB);

roundMaskGraphics = createGraphics(renderer.width, renderer.height);
sourceManager = new SourceManager();

masksRender = new PImage[masksRenderAmount];
sobel = new SobelEdgeDetection();

sourceManager.importURI("/home/giers/.local/bin/fast-style-transfer/data/train2014");
//sourceManager.importURI(dataPath(""));
}


void draw() {
updateServer();
sourceManager.update(); //will write some image to the renderer
sourceManager.setSource();
fxManager.run(true, true); //boolean animate (iterative calcs), boolean apply (draw)
render();
background(greenBackground ? color(0, 255, 0) : color(0));
imageMode(CENTER);
viewport = renderer.get();
if (renderer.width < renderer.height) {
viewport.resize(0, height);
if (viewport.width > width) viewport.resize(width, 0);
} else {
viewport.resize(width, 0);
if (viewport.height > height) viewport.resize(0, height);
}
if (roundMask) {
roundMaskGraphics.setSize(viewport.width, viewport.height);
roundMaskGraphics.beginDraw();
roundMaskGraphics.noStroke();
roundMaskGraphics.background(0);
roundMaskGraphics.fill(255);
roundMaskGraphics.ellipse(viewport.width/2, viewport.height/2, min(viewport.width, viewport.height), min(viewport.width, viewport.height));
roundMaskGraphics.endDraw();
roundMaskImage = roundMaskGraphics.get();
viewport.mask(roundMaskImage);
}
//sourceManager.setSource();

//viewport = getEdges(viewport);
//viewport = cannyEdge(viewport);
image(viewport, width/2, height/2);
if (videoRecord) {
videoExport.saveFrame();
fill(#ff0000);
ellipse(width-100,height-100,30,30);
}
if (drawGUI) drawGUI(guiOffsetTop);
if (recording) {
snapshot();
if (airisRendering) {
airisRendering = false;
recording = previousRecordState;
renderSize = previousRenderSize;
println("i rendered something big, oops");
}
}
}

+ 40
- 0
mint.pde View File

/*

artifactUri — the original artwork digital file.
displayUri — a smaller-scale version of the artwork used for the HEN website feed.
thumbnailUri — currently, this points to the same image for all of the artwork on HEN.

{
"name": "HEN-Mesh",
"description": "Mesh design of the HicEtNunc logo",
"tags": [
"CG",
"3D",
"B3D",
"GEO",
"WIREFRAME",
"B&W",
"COMPLEX"
],
"symbol": "OBJKT",
"artifactUri":
"ipfs://QmS1r91dZadi4XQ6TuFcUVTUBnhphS7B428YdfETfjs6yL",
"displayUri":
"ipfs://QmXNMJVFtnCiZuLDgRFgoMCLG3JyMZXX4JP8qQ9cKtvG8g",
"thumbnailUri":
"ipfs://QmNrhZHUaEqxhyLfqoq1mtHSipkWHeT31LNHb1QEbDHgnc",
"creators": [
"tz1XtjZTzEM6EQ3TnUPUQviCD6WfcsZRHXbj"
],
"formats": [
{
"uri":
"ipfs://QmS1r91dZadi4XQ6TuFcUVTUBnhphS7B428YdfETfjs6yL",
"mimeType": "image/jpeg"
}
],
"decimals": 0,
"isBooleanAmount": false,
"shouldPreferSymbol": false
}
*/

+ 136
- 0
net.pde View File

import processing.net.*;
int port = 10002;
Server composiorServer;

void updateServer() {
Client thisClient = composiorServer.available();
if (thisClient != null) {
if (thisClient.available() > 0) {
String msg = thisClient.readString().toString();
println("Bot reads: " + msg);
String arr[] = msg.split(" ");
String cmd = arr[0];
String[] params = Arrays.copyOfRange(arr, 1, arr.length);

println(cmd);
switch(cmd) {
case("add"):
switch(params[0]) {
case("darker"):
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new DARKER());
break;
case("asdfpixelsort"):
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new ASDFPIXELSORT());
break;
case("auecho"):
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new AUECHO());
break;
case("brighter"):
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new BRIGHTER());
break;
case("distorter"):
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new DISTORTER());
break;
case("grauzone"):
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new GRAUZONE());
break;
case("slitscan"):
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new SLITSCAN());
break;
case("wzip"):
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new WZIP());
break;
default:
break;
}
break;
case("remove"):
if (params[0].equals("last")) {
fxManager.removeFx(fxManager.fxList.size()-1);
} else if (params[0].equals("all")) {
for (int i = 0; i < fxManager.fxList.size(); i++) {
fxManager.removeFx(i);
}
fxManager.removeFx(fxManager.fxList.size()-1);
} else {
fxManager.removeFx(int(params[0])-1);
}
break;
case("swap"):
fxManager.swapFx(int(params[0])-1, int(params[1])-1);
break;
case("play"):
if (fxManager.fxList.size() > int(params[0])-1) {
//fxManager.fxList.get(int(params[0])-1).shader.play();
}
break;
case("random"):
if (fxManager.fxList.size() > int(params[0])-1) {
for (int j = 0; j < fxManager.fxList.get(int(params[0])-1).shader.params.size(); j++) {
fxManager.fxList.get(int(params[0])-1).shader.params.get(j).randomize();
}
}
break;
case("pause"):
if (fxManager.fxList.size() > int(params[0])-1) {
//fxManager.fxList.get(int(params[0])-1).shader.pause();
}
break;
case("render"):
airisRender(5000);
break;
case("set"):

if (fxManager.fxList.size() > int(params[0])-1) {

for (int i = 0; i < params.length; i++) {
if (Arrays.asList(fxManager.fxList.get(int(params[0])-1).shader.getParamNames()).contains(params[i])) {
String attemptedCommand = params[i];
println(fxManager.fxList.get(int(params[0])-1).shader.paramIdByName(params[i]));
try {
if (isNumeric(params[i+1])) {
attemptedCommand += params[i+1];
println(attemptedCommand);
if (fxManager.fxList.get(int(params[0])-1).shader.animating) {
//fxManager.fxList.get(int(params[0])-1).shader.pause();
}
fxManager.fxList.get(int(params[0])-1).shader.params.get(fxManager.fxList.get(int(params[0])-1).shader.paramIdByName(params[i])).setValue(float(params[i+1]));
}
}
catch(Exception e) {
println(e);
println("Error parsing parameters in set");
}
}
}
/*

println(params);
println(fxManager.fxList.get(int(params[0])-1).shader.commands);
if (Arrays.asList(fxManager.fxList.get(int(params[0])-1).shader.commands).contains(params[1])) {
fxManager.fxList.get(int(params[0])-1).shader.pause();
fxManager.fxList.get(int(params[0])-1).shader.setValue(params[1], float(params[2]));
} else {
println("Parameter not found " + params[1]);
}
*/
}
break;
default:
break;
}
}
}
}
public static boolean isNumeric(String strNum) {
if (strNum == null) {
return false;
}
try {
double d = Double.parseDouble(strNum);
}
catch (NumberFormatException nfe) {
return false;
}
return true;
}

+ 114
- 0
oscillator.pde View File

//Osci osci, osci_shifted;

final static int SIN = 0; //add 0.25 to phase to get cos
final static int TAN = 1;
final static int LINE = 2;
final static int SQUARE = 3; //switches between -1 and 1, that's all
final static int RAMP = 4; //line for half the sequence up to 1, then stay at 1 for the other half
final static int RAMPUPDOWN = 5; //line up, stay, line down, stay. use this when drawing a square once for x and once for y with a phaseshift of .. what was it.. 0.5 or 0.25. try it
final static int COS = 6;
final static int RANDOM = 7;

final static int INTVAL = 100;
final static int FLOATVAL = 101;


class Osci { //it's a wave generator
float delta;
float beats;
float inc;
boolean playing;
int mode;
int[] modes;
float phaseshift;
float value;
float startFrame; //resets after every playthrough
//color c;
Osci(float beats_, float phaseshift_, int mode_) { //how many beats one cycle takes, the more, the longer.
beats = beats_;
phaseshift = phaseshift_;
inc = phaseshift * TWO_PI;
mode = mode_;
modes = new int[1];
modes[0] = mode;
start();
}
/*
Osci(int[] modes_) { //for random
int[] possibleBeats = {1, 2, 4, 8, 16, 32, 64};
beats = possibleBeats[(int)random(possibleBeats.length)];
modes = modes_;
phaseshift = (random(1) > .8) ? .25 : 0;
inc = phaseshift * TWO_PI;
mode = modes[0];
start();
}*/
void start() { /// start - reset
delta = (8 * TWO_PI / beats) / ((60 * frameRate) / bpm);
playing = true;
startFrame = frameCount;
}
void stop() {
playing = false;
}
void update() {
if (playing) {
inc += delta;
if (inc > beats*16*TWO_PI) inc -= beats*16*TWO_PI;
switch(mode) {
case(SIN):
value = sin(inc);
break;
case(COS):
value = cos(inc);
break;
case(TAN):
value = tan(inc);
break;
case(LINE):
value = ((inc % TWO_PI)-PI)/PI;
//value = ((inc % (TWO_PI-(TWO_PI*phaseshift)))-PI)/PI*1+2*phaseshift;
//println(inc % TWO_PI);
break;
case(SQUARE):
value = sin(inc+(phaseshift*TWO_PI)) > 0 ? 1 : -1;
break;
case(RAMP):
value = sin(inc) > 0 ? ((inc % TWO_PI)-PI)/PI : 0;
break;
case(RAMPUPDOWN):
if (sin(inc) < -0.666666666) {
value = -0.666666666;
} else if (sin(inc) < 0.666666666 && sin(inc) > -0.666666666) {
value = sin(inc);
} else if (sin(inc) < 1 && sin(inc) > 0.666666666) {
value = 0.666666666;
}
value *= 1.5;
break;
default:
break;
}
value = constrain(value, -1, 1);
if (frameCount > startFrame + (((60 * frameRate) / bpm) * beats) /2) {
value = (mode == RANDOM) ? random(-1, 1) : value;
//println("beat hit. that's " + str(frameCount - startFrame) + " frames since the last beat");
startFrame += (((60 * frameRate) / bpm) * beats) /2;
onRepeat();
}
value = map(value, -1, 1, 0, 1);
}
}

void onRepeat() {
//println("beat played..");
//background(c);
}
/*
void display() {
fill(0);
stroke(2);
strokeWeight(3);
point(width/2, ((value + 1) / 2)* height);
}*/
}

+ 751
- 0
render_airis.pde View File

//"rendering" in terms of "render to disk", not to screen. that is given in draw()

PImage sobelEdgeImg;
PImage sobelEdgeImg2;
PImage cannyEdgeImg;
PImage cannyEdgeImg2;
PGraphics renderFiltered;

PImage[] masksRender;
int masksRenderAmount = 3; //for airis
int masksSize = 1024;

//PImage roundMaskImage; //for obs-studio greenscreenremoval // have the source be in a circle


void render() {
if (airisRendering) {
//render grayscale image
renderFiltered = createGraphics((renderer.width < renderer.height) ? int(map(renderer.width, 0, renderer.height, 0, masksSize)) : masksSize, (renderer.width < renderer.height) ? masksSize : int(map(renderer.height, 0, renderer.width, 0, masksSize)));
renderFiltered.beginDraw();
renderFiltered.image(renderer, 0, 0, renderFiltered.width, renderFiltered.height);
renderFiltered.endDraw();
//sobelEdgeImg = sobelEdge(renderFiltered);
//sobelEdgeImg = sobelEdge(sobelEdgeImg);
//sobelEdgeImg.filter(INVERT); //<- best sobel results here
//cannyEdgeImg = cannyEdge(renderFiltered); //better look bellow
renderFiltered.beginDraw();
renderFiltered.filter(GRAY);
renderFiltered.filter(POSTERIZE, masksRenderAmount);
//renderFiltered. giers PUT A CONTRAST CORRECTION HERE!
renderFiltered.loadPixels();
renderFiltered.endDraw();
cannyEdgeImg2 = cannyEdge(renderFiltered); //<- best canny results here
//sobelEdgeImg2 = sobelEdge(renderFiltered); //better look above


//render mask layers
PImage imgRenderFiltered = renderFiltered.get();
imgRenderFiltered.loadPixels();
color[] c = new color[masksRender.length];
int cc = 0;
for (int i = 0; i < renderFiltered.width*renderFiltered.height; i ++) {
boolean exists = false;
for (int j = 0; j < c.length; j++) {
if (color(renderFiltered.pixels[i]) == c[j]) exists = true;
}
if (!exists) {
c[cc] = color(renderFiltered.pixels[i]);
cc++;
}
}
for (int i = 0; i < masksRender.length; i ++) {
masksRender[i] = createImage(renderFiltered.width, renderFiltered.height, ARGB);
masksRender[i].loadPixels();
for (int j = 0; j < masksRender[i].width*masksRender[i].height; j++) {
if (c[i] == color(imgRenderFiltered.pixels[j])) {
masksRender[i].pixels[j] = color(255);
} else {
masksRender[i].pixels[j] = color(0);
}
}
}

// render edge image
/* old, processing edge detection example
float[][] kernel = {{ -1, -1, -1},
{ -1, 9, -1},
{ -1, -1, -1}};
edgeImg = createImage(renderFiltered.width, renderFiltered.height, RGB);
for (int y = 1; y < renderFiltered.height-1; y++) {
for (int x = 1; x < renderFiltered.width-1; x++) {
float sum = 0;
for (int ky = -1; ky <= 1; ky++) {
for (int kx = -1; kx <= 1; kx++) {
int pos = (y + ky)*renderFiltered.width + (x + kx);
float val = red(renderFiltered.pixels[pos]);
sum += kernel[ky+1][kx+1] * val;
}
}
edgeImg.pixels[y*renderFiltered.width + x] = color(sum, sum, sum);
}
}
edgeImg.updatePixels();
*/
}
}


void airisRender(int size) {
if (!airisRendering) {
airisRendering = true;
previousRenderSize = renderSize;
previousRecordState = recording;
renderSize = size;
recording = true;
}
}

boolean airisRendering;
int previousRenderSize;
boolean previousRecordState;

void snapshot() {
frameName = str(frameCount + int(uptime));
if (airisRendering) {
String renderPath = dataPath("")+"/snapshots/" + frameName + "_rendered/";
renderer.save(renderPath + frameName + ".png");
//edgeImg.save(renderPath + frameName + "_edges.bmp");
//exec(dataPath("potrace"), "--svg", renderPath + frameName + "_edges.bmp", "-o", renderPath + frameName + "_edges.svg");
//sobelEdgeImg.save(renderPath + frameName + "_edgeSobel.png");
//cannyEdgeImg.save(renderPath + frameName + "_edgeCanny.png");
//cannyEdgeImg2.save(renderPath + frameName + "_edgeCanny2.png");
cannyEdgeImg2.save(renderPath + frameName + "_edge.png");
//edgeImg2.save(renderPath + frameName + "_edges2.png");
//renderFiltered.save(renderPath + frameName + "_filtered.png");

//pack 3 masks into one image
PImage packedMasks = createImage(masksRender[0].width, masksRender[0].height, RGB);
packedMasks.loadPixels();


for (int i = 0; i < masksRender.length; i ++) {
masksRender[i].save(renderPath + frameName + "_mask_" + i + ".png");
}
for (int j = 0; j < masksRender[0].pixels.length; j++) {
packedMasks.pixels[j] = color(red(masksRender[0].pixels[j]), green(masksRender[1].pixels[j]), blue(masksRender[2].pixels[j]));
}
packedMasks.updatePixels();
packedMasks.save(renderPath + frameName + "_masks_packed.png");

composiorServer.write("images " + renderer.width + " " + renderer.height + " " + renderPath);
println("Rendered & Message sent");
} else {
renderer.save(dataPath("")+"/snapshots/" + frameName + ".png");
}
saveData[1] = "uptime = " + frameName;
println("Rendered " + frameName + ".png at " + dataPath("")+"/snapshots/ with a resolution of " + renderer.width + " x " + renderer.height);
saveStrings(dataPath("saves.sav"), saveData);
}




//the following two effects were not implemented as fx-shaders.
//these are just for iris // vector tracing

/*******************************************
* CANNY EDGE DETECTOR FOR VECTOR TRACING
*******************************************/

import java.awt.image.BufferedImage;
import java.util.Arrays;


PImage cannyEdge(PImage img){
CannyEdgeDetector detector = new CannyEdgeDetector();
detector.setLowThreshold(0.5f);
detector.setHighThreshold(1f);
detector.setSourceImage((java.awt.image.BufferedImage)img.getImage());
detector.process();
BufferedImage edges = detector.getEdgesImage();
PImage changed = new PImage(edges);
return changed;
}

// The code below is taken from "http://www.tomgibara.com/computer-vision/CannyEdgeDetector.java"
// I have stripped the comments for conciseness

public class CannyEdgeDetector {

// statics

private final static float GAUSSIAN_CUT_OFF = 0.005f;
private final static float MAGNITUDE_SCALE = 100F;
private final static float MAGNITUDE_LIMIT = 1000F;
private final static int MAGNITUDE_MAX = (int) (MAGNITUDE_SCALE * MAGNITUDE_LIMIT);

// fields

private int height;
private int width;
private int picsize;
private int[] data;
private int[] magnitude;
private BufferedImage sourceImage;
private BufferedImage edgesImage;

private float gaussianKernelRadius;
private float lowThreshold;
private float highThreshold;
private int gaussianKernelWidth;
private boolean contrastNormalized;

private float[] xConv;
private float[] yConv;
private float[] xGradient;
private float[] yGradient;

// constructors

/**
* Constructs a new detector with default parameters.
*/

public CannyEdgeDetector() {
lowThreshold = 2.5f;
highThreshold = 7.5f;
gaussianKernelRadius = 2f;
gaussianKernelWidth = 16;
contrastNormalized = false;
}



public BufferedImage getSourceImage() {
return sourceImage;
}


public void setSourceImage(BufferedImage image) {
sourceImage = image;
}


public BufferedImage getEdgesImage() {
return edgesImage;
}


public void setEdgesImage(BufferedImage edgesImage) {
this.edgesImage = edgesImage;
}


public float getLowThreshold() {
return lowThreshold;
}


public void setLowThreshold(float threshold) {
if (threshold < 0) throw new IllegalArgumentException();
lowThreshold = threshold;
}

public float getHighThreshold() {
return highThreshold;
}


public void setHighThreshold(float threshold) {
if (threshold < 0) throw new IllegalArgumentException();
highThreshold = threshold;
}

public int getGaussianKernelWidth() {
return gaussianKernelWidth;
}

public void setGaussianKernelWidth(int gaussianKernelWidth) {
if (gaussianKernelWidth < 2) throw new IllegalArgumentException();
this.gaussianKernelWidth = gaussianKernelWidth;
}

public float getGaussianKernelRadius() {
return gaussianKernelRadius;
}

public void setGaussianKernelRadius(float gaussianKernelRadius) {
if (gaussianKernelRadius < 0.1f) throw new IllegalArgumentException();
this.gaussianKernelRadius = gaussianKernelRadius;
}

public boolean isContrastNormalized() {
return contrastNormalized;
}

public void setContrastNormalized(boolean contrastNormalized) {
this.contrastNormalized = contrastNormalized;
}

// methods

public void process() {
width = sourceImage.getWidth();
height = sourceImage.getHeight();
picsize = width * height;
initArrays();
readLuminance();
if (contrastNormalized) normalizeContrast();
computeGradients(gaussianKernelRadius, gaussianKernelWidth);
int low = Math.round(lowThreshold * MAGNITUDE_SCALE);
int high = Math.round( highThreshold * MAGNITUDE_SCALE);
performHysteresis(low, high);
thresholdEdges();
writeEdges(data);
}

// private utility methods

private void initArrays() {
if (data == null || picsize != data.length) {
data = new int[picsize];
magnitude = new int[picsize];

xConv = new float[picsize];
yConv = new float[picsize];
xGradient = new float[picsize];
yGradient = new float[picsize];
}
}
private void computeGradients(float kernelRadius, int kernelWidth) {

//generate the gaussian convolution masks
float kernel[] = new float[kernelWidth];
float diffKernel[] = new float[kernelWidth];
int kwidth;
for (kwidth = 0; kwidth < kernelWidth; kwidth++) {
float g1 = gaussian(kwidth, kernelRadius);
if (g1 <= GAUSSIAN_CUT_OFF && kwidth >= 2) break;
float g2 = gaussian(kwidth - 0.5f, kernelRadius);
float g3 = gaussian(kwidth + 0.5f, kernelRadius);
kernel[kwidth] = (g1 + g2 + g3) / 3f / (2f * (float) Math.PI * kernelRadius * kernelRadius);
diffKernel[kwidth] = g3 - g2;
}

int initX = kwidth - 1;
int maxX = width - (kwidth - 1);
int initY = width * (kwidth - 1);
int maxY = width * (height - (kwidth - 1));

//perform convolution in x and y directions
for (int x = initX; x < maxX; x++) {
for (int y = initY; y < maxY; y += width) {
int index = x + y;
float sumX = data[index] * kernel[0];
float sumY = sumX;
int xOffset = 1;
int yOffset = width;
for (; xOffset < kwidth; ) {
sumY += kernel[xOffset] * (data[index - yOffset] + data[index + yOffset]);
sumX += kernel[xOffset] * (data[index - xOffset] + data[index + xOffset]);
yOffset += width;
xOffset++;
}

yConv[index] = sumY;
xConv[index] = sumX;
}
}

for (int x = initX; x < maxX; x++) {
for (int y = initY; y < maxY; y += width) {
float sum = 0f;
int index = x + y;
for (int i = 1; i < kwidth; i++)
sum += diffKernel[i] * (yConv[index - i] - yConv[index + i]);

xGradient[index] = sum;
}
}

for (int x = kwidth; x < width - kwidth; x++) {
for (int y = initY; y < maxY; y += width) {
float sum = 0.0f;
int index = x + y;
int yOffset = width;
for (int i = 1; i < kwidth; i++) {
sum += diffKernel[i] * (xConv[index - yOffset] - xConv[index + yOffset]);
yOffset += width;
}

yGradient[index] = sum;
}
}

initX = kwidth;
maxX = width - kwidth;
initY = width * kwidth;
maxY = width * (height - kwidth);
for (int x = initX; x < maxX; x++) {
for (int y = initY; y < maxY; y += width) {
int index = x + y;
int indexN = index - width;
int indexS = index + width;
int indexW = index - 1;
int indexE = index + 1;
int indexNW = indexN - 1;
int indexNE = indexN + 1;
int indexSW = indexS - 1;
int indexSE = indexS + 1;

float xGrad = xGradient[index];
float yGrad = yGradient[index];
float gradMag = hypot(xGrad, yGrad);

//perform non-maximal supression
float nMag = hypot(xGradient[indexN], yGradient[indexN]);
float sMag = hypot(xGradient[indexS], yGradient[indexS]);
float wMag = hypot(xGradient[indexW], yGradient[indexW]);
float eMag = hypot(xGradient[indexE], yGradient[indexE]);
float neMag = hypot(xGradient[indexNE], yGradient[indexNE]);
float seMag = hypot(xGradient[indexSE], yGradient[indexSE]);
float swMag = hypot(xGradient[indexSW], yGradient[indexSW]);
float nwMag = hypot(xGradient[indexNW], yGradient[indexNW]);
float tmp;

if (xGrad * yGrad <= (float) 0 /*(1)*/
? Math.abs(xGrad) >= Math.abs(yGrad) /*(2)*/
? (tmp = Math.abs(xGrad * gradMag)) >= Math.abs(yGrad * neMag - (xGrad + yGrad) * eMag) /*(3)*/
&& tmp > Math.abs(yGrad * swMag - (xGrad + yGrad) * wMag) /*(4)*/
: (tmp = Math.abs(yGrad * gradMag)) >= Math.abs(xGrad * neMag - (yGrad + xGrad) * nMag) /*(3)*/
&& tmp > Math.abs(xGrad * swMag - (yGrad + xGrad) * sMag) /*(4)*/
: Math.abs(xGrad) >= Math.abs(yGrad) /*(2)*/
? (tmp = Math.abs(xGrad * gradMag)) >= Math.abs(yGrad * seMag + (xGrad - yGrad) * eMag) /*(3)*/
&& tmp > Math.abs(yGrad * nwMag + (xGrad - yGrad) * wMag) /*(4)*/
: (tmp = Math.abs(yGrad * gradMag)) >= Math.abs(xGrad * seMag + (yGrad - xGrad) * sMag) /*(3)*/
&& tmp > Math.abs(xGrad * nwMag + (yGrad - xGrad) * nMag) /*(4)*/
) {
magnitude[index] = gradMag >= MAGNITUDE_LIMIT ? MAGNITUDE_MAX : (int) (MAGNITUDE_SCALE * gradMag);
//NOTE: The orientation of the edge is not employed by this
//implementation. It is a simple matter to compute it at
//this point as: Math.atan2(yGrad, xGrad);
} else {
magnitude[index] = 0;
}
}
}
}

private float hypot(float x, float y) {
return (float) Math.hypot(x, y);
}

private float gaussian(float x, float sigma) {
return (float) Math.exp(-(x * x) / (2f * sigma * sigma));
}

private void performHysteresis(int low, int high) {

Arrays.fill(data, 0);

int offset = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (data[offset] == 0 && magnitude[offset] >= high) {
follow(x, y, offset, low);
}
offset++;
}
}
}

private void follow(int x1, int y1, int i1, int threshold) {
int x0 = x1 == 0 ? x1 : x1 - 1;
int x2 = x1 == width - 1 ? x1 : x1 + 1;
int y0 = y1 == 0 ? y1 : y1 - 1;
int y2 = y1 == height -1 ? y1 : y1 + 1;

data[i1] = magnitude[i1];
for (int x = x0; x <= x2; x++) {
for (int y = y0; y <= y2; y++) {
int i2 = x + y * width;
if ((y != y1 || x != x1)
&& data[i2] == 0
&& magnitude[i2] >= threshold) {
follow(x, y, i2, threshold);
return;
}
}
}
}

private void thresholdEdges() {
for (int i = 0; i < picsize; i++) {
data[i] = data[i] > 0 ? -1 : 0xff000000;
}
}

private int luminance(float r, float g, float b) {
return Math.round(0.299f * r + 0.587f * g + 0.114f * b);
}

private void readLuminance() {
int type = sourceImage.getType();
if (type == BufferedImage.TYPE_INT_RGB || type == BufferedImage.TYPE_INT_ARGB) {
int[] pixels = (int[]) sourceImage.getData().getDataElements(0, 0, width, height, null);
for (int i = 0; i < picsize; i++) {
int p = pixels[i];
int r = (p & 0xff0000) >> 16;
int g = (p & 0xff00) >> 8;
int b = p & 0xff;
data[i] = luminance(r, g, b);
}
} else if (type == BufferedImage.TYPE_BYTE_GRAY) {
byte[] pixels = (byte[]) sourceImage.getData().getDataElements(0, 0, width, height, null);
for (int i = 0; i < picsize; i++) {
data[i] = (pixels[i] & 0xff);
}
} else if (type == BufferedImage.TYPE_USHORT_GRAY) {
short[] pixels = (short[]) sourceImage.getData().getDataElements(0, 0, width, height, null);
for (int i = 0; i < picsize; i++) {
data[i] = (pixels[i] & 0xffff) / 256;
}
} else if (type == BufferedImage.TYPE_3BYTE_BGR) {
byte[] pixels = (byte[]) sourceImage.getData().getDataElements(0, 0, width, height, null);
int offset = 0;
for (int i = 0; i < picsize; i++) {
int b = pixels[offset++] & 0xff;
int g = pixels[offset++] & 0xff;
int r = pixels[offset++] & 0xff;
data[i] = luminance(r, g, b);
}
} else {
throw new IllegalArgumentException("Unsupported image type: " + type);
}
}

private void normalizeContrast() {
int[] histogram = new int[256];
for (int i = 0; i < data.length; i++) {
histogram[data[i]]++;
}
int[] remap = new int[256];
int sum = 0;
int j = 0;
for (int i = 0; i < histogram.length; i++) {
sum += histogram[i];
int target = sum*255/picsize;
for (int k = j+1; k <=target; k++) {
remap[k] = i;
}
j = target;
}

for (int i = 0; i < data.length; i++) {
data[i] = remap[data[i]];
}
}

private void writeEdges(int pixels[]) {
if (edgesImage == null) {
edgesImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
edgesImage.getWritableTile(0, 0).setDataElements(0, 0, width, height, pixels);
}
}


/***************************************
* SOBELEDGE DETECTION FOR VECTOR TRACING
***************************************/


SobelEdgeDetection sobel;

PImage sobelEdge(PImage img) {
PImage g_img = sobel.findEdgesAll(img, 90);
g_img = sobel.noiseReduction(g_img, 1);
return(g_img);
}


class SobelEdgeDetection
{

// Sobel Edge Detection strandard, this applies the edge detection algorithm across the entire image and returns the edge image
public PImage findEdgesAll(PImage img, int tolerance)
{
PImage buf = createImage( img.width, img.height, ARGB );

int GX[][] = new int[3][3];
int GY[][] = new int[3][3];
int sumRx = 0;
int sumGx = 0;
int sumBx = 0;
int sumRy = 0;
int sumGy = 0;
int sumBy = 0;
int finalSumR = 0;
int finalSumG = 0;
int finalSumB = 0;

// 3x3 Sobel Mask for X
GX[0][0] = -1;
GX[0][1] = 0;
GX[0][2] = 1;
GX[1][0] = -2;
GX[1][1] = 0;
GX[1][2] = 2;
GX[2][0] = -1;
GX[2][1] = 0;
GX[2][2] = 1;

// 3x3 Sobel Mask for Y
GY[0][0] = 1;
GY[0][1] = 2;
GY[0][2] = 1;
GY[1][0] = 0;
GY[1][1] = 0;
GY[1][2] = 0;
GY[2][0] = -1;
GY[2][1] = -2;
GY[2][2] = -1;

buf.loadPixels();

for(int y = 0; y < img.height; y++)
{
for(int x = 0; x < img.width; x++)
{
if(y==0 || y==img.height-1) {
}
else if( x==0 || x == img.width-1 ) {
}
else
{

// Convolve across the X axis and return gradiant aproximation
for(int i = -1; i <= 1; i++)
for(int j = -1; j <= 1; j++)
{
color col = img.get(x + i, y + j);
float r = red(col);
float g = green(col);
float b = blue(col);


sumRx += r * GX[ i + 1][ j + 1];
sumGx += g * GX[ i + 1][ j + 1];
sumBx += b * GX[ i + 1][ j + 1];

}

// Convolve across the Y axis and return gradiant aproximation
for(int i = -1; i <= 1; i++)
for(int j = -1; j <= 1; j++)
{
color col = img.get(x + i, y + j);
float r = red(col);
float g = green(col);
float b = blue(col);


sumRy += r * GY[ i + 1][ j + 1];
sumGy += g * GY[ i + 1][ j + 1];
sumBy += b * GY[ i + 1][ j + 1];

}

finalSumR = abs(sumRx) + abs(sumRy);
finalSumG = abs(sumGx) + abs(sumGy);
finalSumB = abs(sumBx) + abs(sumBy);


// I only want to return a black or a white value, here I determine the greyscale value,
// and if it is above a tolerance, then set the colour to white

float gray = (finalSumR + finalSumG + finalSumB) / 3;
if(gray > tolerance)
{
finalSumR = 0;
finalSumG = 0;
finalSumB = 0;
}
else
{
finalSumR = 255;
finalSumG = 255;
finalSumB = 255;
}



buf.pixels[ x + (y * img.width) ] = color(finalSumR, finalSumG, finalSumB);

sumRx=0;
sumGx=0;
sumBx=0;
sumRy=0;
sumGy=0;
sumBy=0;

}

}

}

buf.updatePixels();

return buf;
}



public PImage noiseReduction(PImage img, int kernel)
{
PImage buf = createImage( img.width, img.height, ARGB );

buf.loadPixels();

for(int y = 0; y < img.height; y++)
{
for(int x = 0; x < img.width; x++)
{

int sumR = 0;
int sumG = 0;
int sumB = 0;

// Convolute across the image, averages out the pixels to remove noise
for(int i = -kernel; i <= kernel; i++)
{
for(int j = -kernel; j <= kernel; j++)
{
color col = img.get(x+i,y+j);
float r = red(col);
float g = green(col);
float b = blue(col);

if(r==255) sumR++;
if(g==255) sumG++;
if(b==255) sumB++;
}
}

int halfKernel = (((kernel*2)+1) * ((kernel*2)+1)) / 2 ;

if(sumR > halfKernel ) sumR=255;
else sumR= 0;
if(sumG > halfKernel ) sumG=255;
else sumG= 0;
if(sumB > halfKernel ) sumB=255;
else sumB= 0;


buf.pixels[ x + (y * img.width) ] = color(sumR, sumG, sumB);

}


}
buf.updatePixels();

return buf;
}


}

+ 112
- 0
shader.pde View File

class Shader {
int id;
int number;
String name;
boolean animating = true;
ArrayList<Param> params = new ArrayList<Param>();

class Param {
int type;
String name;
float minValue, maxValue;
float value;
float inc;
boolean animating;
int[] osciModes;
//Osci[] oscis;
Osci osci;
//incrementer -- in bpm


Param(String paramName, int maxValue_, int[] osciModes_) {
name = paramName;
maxValue = maxValue_;
minValue = 0;
type = INTVAL; //int
osciModes = osciModes_;
makeOsci();
play();
}
Param(String paramName, float minValue_, float maxValue_, int[] osciModes_) {
name = paramName;
minValue = minValue_;
maxValue = maxValue_;
type = FLOATVAL; //float
osciModes = osciModes_;
makeOsci();
play();
}

void makeOsci() {
int[] possibleBeats = {1, 2, 4, 8, 16, 32, 64};
int beats = possibleBeats[(int)random(possibleBeats.length)];
int mode = osciModes[(int)random(osciModes.length)];
float phaseshift = (random(1) > .8) ? .25 : 0;
osci = new Osci(beats, phaseshift, mode);
}

void play() {
animating = true;
}
void pause() {
animating = false;
}
void animate() {
osci.update();
value = getValue(osci.value, false);
};
void randomize() {
if (type == INTVAL) {
value = (int)random(minValue, maxValue);
} else if (type == FLOATVAL) {
//value = random(minValue, maxValue);
value = random(minValue, maxValue);
}
}

String formattedValue() {
if (type == INTVAL) {
return str((int)value);
} else if (type == FLOATVAL) {
return nf(getValue(value, true), 0, 2).replace(',', '.').replace(' ', ',');
} else {
return "";
}
}

float getValue(float val, boolean normalize) { //used for other function, dont use it
return normalize ? map(val, minValue, maxValue, 0, 1) : map(val, 0, 1, minValue, maxValue);
}

void setValue(float value_) {
if (type == INTVAL) {
value = constrain((int)value_, 0, maxValue);
} else if (type == FLOATVAL) {
value = getValue(value_, false);
}
}
}
void apply() {
}; //override me

String[] getParamNames() {
String[] pnames = new String[params.size()];
for (int i = 0; i < params.size(); i++) {
pnames[i] = params.get(i).name;
}
return pnames;
}
int paramIdByName(String name_) {

for (int i = 0; i < params.size(); i ++) {
if (params.get(i).name.equals(name_)) {
return i;
}
}
return -1;
}
}
/*
*/

+ 153
- 0
source.pde View File


Capture cam;
Movie movie;
boolean moviePlaying;
PImage fallbackImage;

void movieEvent(Movie m) {
if (moviePlaying) {
m.read();
if (mode == 1) {
sourceManager.setImage(movie.get());
movie.jump(random(movie.duration()));
}
}
}
void newMovie(String path) {
movie = new Movie(this, path);
}

boolean isVideo(String path) {
String fpl = path.toLowerCase();
if (fpl.endsWith(".mp4") || fpl.endsWith(".avi") || fpl.endsWith(".webm") || fpl.endsWith(".mkv") || fpl.endsWith(".mov")) return true;
else return false;
}
boolean isImage(String path) {
String fpl = path.toLowerCase();
if (fpl.endsWith(".bmp") || fpl.endsWith(".png") || fpl.endsWith(".jpg") || fpl.endsWith(".jpeg") || fpl.endsWith(".gif")) return true; //gif = special case!
else return false;
}

class SourceManager { //no constructor

// This function returns all the files in a directory as an array of Strings
String[] listFileNames(String dir) {
File file = new File(dir);
if (file.isDirectory()) {
String names[] = file.list();
return names;
} else {
return null;
}
}


String dir;
String[] selection;
int selId;
void importURI(String path) {
File file = new File(path);
if (file.isDirectory()) {
dir = path;
String names[] = file.list();
ArrayList<String> usableFiles = new ArrayList<String>();
for (int i = 0; i < names.length; i++) {
if (isImage(names[i]) || isVideo(names[i])) {
usableFiles.add(names[i]);
}
}
selection = new String[usableFiles.size()];
for (int i = 0; i < usableFiles.size(); i++) selection[i] = usableFiles.get(i);
println("Got new selection from folder. " + selection.length + " usable files.");
path = dir + "/" + selection[(int)random(selection.length)];
}


if (isImage(path) || isVideo(path)) {
println("Importing file " + path);
if (moviePlaying) movie.stop();
if (isImage(path)) {
moviePlaying = false;
setImage(loadImage(path));
} else if (isVideo(path)) {
moviePlaying = true;
newMovie(path);
movie.loop();
}
}
}


void fallback() {
println("Fallback");
mode = 1;
setImage(fallbackImage); //fallbackImage should always be a copy of the last image that worked
}

void update() {
//check if source image is present
if (mode == 0) {
try {
if (cam.available() == true) {
cam.read();
if (cam != null) {
source = cam.get();
} else {
fallback();
}
}
}
catch (Exception e) {
println(e);
println("No cam available, falling back to image..");
fallback();
}
}
if (source == null) {
fallback();
}

int toW, toH;
if (source.width > source.height) {
toW = renderSize;
toH = int(map(source.height, 0, source.width, 0, renderSize));
} else {
toW = int(map(source.width, 0, source.height, 0, renderSize));
toH = renderSize;
}
toW = (toW % 2 == 0) ? toW : toW+1;
toH = (toH % 2 == 0) ? toH : toH+1;

renderer.setSize(toW, toH);
}


void setImage(PImage img) { //set image to source
source = img.get();
fallbackImage = source;
}

void setSource() { //set source to renderer


renderer.beginDraw();
if (mode == 0) {
try { //final check for source image being present & valid
renderer.beginDraw(); //pre-fx
renderer.tint(255, 220, 200); //beautify me (color correct webcam image)
renderer.image(source, 0, 0, renderer.width, renderer.height);
renderer.noTint();
}
catch(Exception e) {
println("error here as well");
}
}
if (mode == 1) {
//else if (mode == 1){

renderer.image(source, 0, 0, renderer.width, renderer.height);
}

renderer.endDraw();
}
}

+ 179
- 0
ui.pde View File

void mousePressed()
{
if (mouseButton == LEFT) {
if (sourceManager.dir != null) {
sourceManager.importURI(sourceManager.dir + "/" + sourceManager.selection[(int)random(sourceManager.selection.length)]);
}
}
if (mouseButton == RIGHT) {
snapshot();
}
}
boolean videoRecord;
void mouseWheel(MouseEvent event) {

if (event.getCount() < 0) renderSize += 8;
else renderSize -= 8;
renderSize = constrain(renderSize, 8, 15000);
println("Render size: " + renderSize);
}

String[] params;
void keyPressed() {
if (key == 'c') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new DARKER());
}
if (key == 'r') {
for (int i = 0; i < fxManager.fxList.size(); i ++) {
for (int j = 0; j < fxManager.fxList.get(i).shader.params.size(); j++) {
fxManager.fxList.get(i).shader.params.get(j).randomize();
}
}
}

if (key == 'x') {
videoRecord = !videoRecord;
if (videoRecord) {
println("Started video recording");
videoExport = new VideoExport(this, "data/videos/" + str(frameCount + int(uptime)) + ".mp4", renderer);
//String[] settings = {"[ffmpeg]","-y","-f","rawvideo","-vcodec","rawvideo","-s",str(renderer.width)+"x"+str(renderer.height),};
videoExport.setFrameRate(frameRate);
videoExport.setQuality(100, 0); // (crf, audiobitrate)
String videoSize = str(renderer.width)+"x"+str(renderer.height);
videoExport.setFfmpegVideoSettings(
new String[]{
"[ffmpeg]", // ffmpeg executable
"-y", // overwrite old file
"-f", "rawvideo", // format rgb raw
"-vcodec", "rawvideo", // in codec rgb raw
"-s", videoSize, // size
"-pix_fmt", "rgb24", // pix format rgb24
"-r", "[fps]", // frame rate
"-i", "-", // pipe input
//"-vf", "scale="+str(renderer.width)+":"+str(renderer.height)+":force_original_aspect_ratio=decrease",
"-an", // no audio
"-vcodec", "h264", // out codec h264
"-pix_fmt", "yuv420p", // color space yuv420p
"-crf", "[crf]", // quality
"-metadata", "comment=[comment]", // comment
"[output]" // output file
});
videoExport.setDebugging(true);

videoExport.startMovie();
} else {
println("Ended video recording");
videoExport.endMovie();
videoExport.dispose();
}
}
if (key == 'f') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new FM());
}
if (key == 'j') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new DRAWSTROKES());
}
if (key == 'h') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new DRAWGENERATIVE());
}
if (key == 'd') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new ASDFPIXELSORT());
}
if (key == 'b') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new BRIGHTER());
}
if (key == 'e') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new DISTORTER());
}
if (key == 'w') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new WZIP());
}
if (key == 'g') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new GRAUZONE());
}
if (key == 'q') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new SLITSCAN());
}
if (key == ' ') {
}
if (key == 'o') {
renderSize = 10000;
}
if (key == '1') {
mode = 0;
}
if (key == '2') {
if (mode != 1) sourceManager.fallback();
mode = 1;
}
if (keyCode == KeyEvent.VK_F10) {
airisRender(5000); //15000 would be fine as well i guess
}
if (key == 'a') {
if (fxManager.fxList.size() < maxFx) fxManager.addFx(new AUECHO());
}
if (key == 'v') {
fxManager.removeFx(fxManager.fxList.size()-1); //remove last in arraylist
// fxManager.removeFx(2); //remove at position in arraylist
}
/* if (key == 'a') {
params = loadStrings(dataPath("params.txt"));
for (int i = 0; i < params.length; i++) {
println(params[i]);
}
}*/
}


int guiOffsetTop = 0;
boolean guiHidden;
String noparams = "no directly controllable parameters, try play/ pausing to randomize";
void drawGUI(int topOffset) {
fill(255);
for (int i = 0; i < fxManager.fxList.size(); i++) {
textSize(20);
textAlign(RIGHT);
int fi = i+1;
float textOffset = textWidth(fxManager.fxList.get(i).shader.name);
fill(0, 0, 0, 255);
rect(width-(textOffset+54), 8+(i*65)+topOffset, textOffset+54, 30);
fill(255);
text("[" + fi + "] " + fxManager.fxList.get(i).shader.name, -10, 10+(i*65)+topOffset, width, 100);
String playText = (fxManager.fxList.get(i).shader.animating) ? "animated" : "manual set";
fill(75, 75, 75, 255);
rect(width-(textOffset+54+textWidth(playText)), 10+(i*65)+5+topOffset, textWidth(playText), 25);
fill(255);
textAlign(RIGHT);
textSize(15);
text(playText, -(textOffset+65), 10+(i*65)+5+topOffset, width, 100);

textOffset = 0;
for (int j = 0; j < fxManager.fxList.get(i).shader.params.size(); j ++) {
textOffset += textWidth(fxManager.fxList.get(i).shader.params.get(j).name) + textWidth(fxManager.fxList.get(i).shader.params.get(j).formattedValue()) +15;
}
fill(75, 75, 75, 255);
textOffset = (textOffset == 0) ? textWidth(noparams)+15 : textOffset;
rect(width-textOffset-15, 37+(i*65)+topOffset, textOffset+15, 25);

fill(255);
textOffset = 0;
textAlign(RIGHT);
if (fxManager.fxList.get(i).shader.params.size()>0) {
for (int j = 0; j < fxManager.fxList.get(i).shader.params.size(); j ++) {
text(fxManager.fxList.get(i).shader.params.get(j).name + ": " + fxManager.fxList.get(i).shader.params.get(j).formattedValue(), -textOffset-10, 40+(i*65)+topOffset, width, 100);
textOffset += textWidth(fxManager.fxList.get(i).shader.params.get(j).name) + textWidth(fxManager.fxList.get(i).shader.params.get(j).formattedValue()) +15;
}
} else {
text(noparams, -textOffset-10, 40+(i*65)+topOffset, width, 100);
}
}
}




PImage droppedImage;
void dropEvent(DropEvent theDropEvent) {

sourceManager.importURI(theDropEvent.filePath());
}

Loading…
Cancel
Save