// Draw vertical threads on the image // Tomasz Sulej, generateme.blog@gmail.com, http://generateme.tumblr.com // Licence: http://unlicense.org/ // Usage: // * press SPACE to save // * click to change parameters // set up filename String filename = "test"; String fileext = ".jpg"; String foldername = "./"; boolean glow = false; // make image glow int stepsize_init = 500; // maximum segment length int stepsize_final = 20; // minimum segment length float stepsize_ratio = 0.7; // segment length reduction ratio (0 - fast, 1-v. slow) float stroke_size = 1.0; // width of the line boolean make_dots = false; // make dots on line segments // configuration of "curtain" style float v_step_exp = 2.0; // exponent for vertical step 0.5-2.0 int v_step_channel = NBRIGHTNESS; // channel used for vertical step float h_step_exp = 2.0; // 0.5-2.0 int h_step_channel = NBRIGHTNESS; boolean h_step_sin = false; // linear (false) or sinusoidal (true) float h_step_ratio = 5; // -6..-1 and 1..6 boolean ch_v_byte = false; // interpret channel value as byte color bckg_color = color(0,0,0); // background color int max_display_size = 800; // viewing window size (regardless image size) // working buffer PGraphics buffer; // image PImage img; String sessionid; void setup() { sessionid = hex((int)random(0xffff),4); img = loadImage(foldername+filename+fileext); buffer = createGraphics(img.width, img.height); buffer.beginDraw(); buffer.noFill(); buffer.smooth(8); buffer.background(bckg_color); buffer.strokeWeight(stroke_size); buffer.endDraw(); // calculate window size float ratio = (float)img.width/(float)img.height; int neww, newh; if(ratio < 1.0) { neww = (int)(max_display_size * ratio); newh = max_display_size; } else { neww = max_display_size; newh = (int)(max_display_size / ratio); } size(neww,newh); reinit(); } void reinit() { ss_current = stepsize_init; ss_ratio = map(constrain(stepsize_ratio,0,1),0,1,0.9,0.99); dodot = make_dots ? 0 : -1; } void draw() { processImage(); } int ss_current; float ss_ratio; int dodot; final color WHITE = color(255,255,255); PImage _img = null; int getVStep(int x, int y, int size) { float b = getChannel(img.get(x, y),v_step_channel); if(ch_v_byte) b = 128+(int)((byte)(int(b))); float s = pow(map(b, 0, 255, 0, 1),v_step_exp); return 1+(int)(s*size); } int getHStep(int x, int y, int size) { float b = getChannel(img.get(x, y),h_step_channel); if(ch_v_byte) b = 128+(int)((byte)(int(b))); if(h_step_sin) { float s = sin(pow(map(b, 0, 255, 0, 1),h_step_exp)*TWO_PI-PI); return (int)(s*size); } else { float s = pow(map(b, 0, 255, 0, 1),h_step_exp); return (int)(s*size-size/2); } } void processImage() { println("Segment size=" + ss_current); if(glow) { _img = buffer.get(); _img.filter(BLUR,1); } buffer.beginDraw(); // START CODE HERE! use buffer to draw/manipulate for(int i=0;i<50;i++) { int py = 0; int x = (int)random(buffer.width); int px = x; int y = 0; while (y5?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; }