PImage bg, img; PFont font; /** controls

q...i - hilbert sfc dithering with different q
o - 4 color noise diffusion
p - 2 color noise diffusion
a..j - noise diffusion with arbitrary number of gray shades
k - Bill Atkinson's B/W dither
l - Bill Atkinson's COLOR dither
m - grayscale image for reference
spacebar - reset image
*/ void setup() { size(1024,600); //size(400,240); frameRate(15); textMode(SCREEN); font=loadFont("Trivia-Regular-24.vlw"); textFont(font, 24); bg=loadImage("abstracttest.jpg"); img=new PImage(width,height); img.copy(bg,0,0,bg.width,bg.height,0,0,width,height); image(img,0,0); } void atkinsonDither(PImage img) { img.loadPixels(); // img.pixels - vstup loadPixels(); // pixels - vystup color c1 = color(0,0,0); color c2 = color(255,255,255); float bri,err; for (int i=0; i<(width*height); ++i) { bri=brightness(img.pixels[i]); if ( bri<128 ) { pixels[i]=c1; err=bri/8; } else { pixels[i]=c2; err=-((255-bri)/8); } //pixels[i]=color(abs(err*16),bri,bri); if ( i<((width*(height-2))-2) ) { img.pixels[i+1]= color(constrain(brightness(img.pixels[i+1])+err,0,255)); img.pixels[i+2]= color(constrain(brightness(img.pixels[i+2])+err,0,255)); img.pixels[i+width-1]= color(constrain(brightness(img.pixels[i+width-1])+err,0,255)); img.pixels[i+width]= color(constrain(brightness(img.pixels[i+width])+err,0,255)); img.pixels[i+width+1]= color(constrain(brightness(img.pixels[i+width+1])+err,0,255)); img.pixels[i+(2*width)]= color(constrain(brightness(img.pixels[i+(2*width)])+err,0,255)); } } updatePixels(); } void atkinsonColorDither(PImage img) { img.loadPixels(); // img.pixels - vstup loadPixels(); // pixels - vystup color c1 = color(0,0,0); color c2 = color(255,255,255); float r,g,b,rerr,gerr,berr; int j; for (int i=0; i<(width*height); ++i) { r=red(img.pixels[i]); g=green(img.pixels[i]); b=blue(img.pixels[i]); pixels[i]=color(r<128?0:255,g<128?0:255,b<128?0:255); rerr=(r-red(pixels[i]))/8; gerr=(g-green(pixels[i]))/8; berr=(b-blue(pixels[i]))/8; if ( i<((width*(height-2))-2) ) { j=i+1; img.pixels[j]= color( red(img.pixels[j])+rerr, green(img.pixels[j])+gerr, blue(img.pixels[j])+berr ); j=i+2; img.pixels[j]= color( red(img.pixels[j])+rerr, green(img.pixels[j])+gerr, blue(img.pixels[j])+berr ); j=i+width-1; img.pixels[j]= color( red(img.pixels[j])+rerr, green(img.pixels[j])+gerr, blue(img.pixels[j])+berr ); j=i+width; img.pixels[j]= color( red(img.pixels[j])+rerr, green(img.pixels[j])+gerr, blue(img.pixels[j])+berr ); j=i+width+1; img.pixels[j]= color( red(img.pixels[j])+rerr, green(img.pixels[j])+gerr, blue(img.pixels[j])+berr ); j=i+(2*width); img.pixels[j]= color( red(img.pixels[j])+rerr, green(img.pixels[j])+gerr, blue(img.pixels[j])+berr ); /* img.pixels[i+1]= color(constrain(brightness(img.pixels[i+1])+err,0,255)); img.pixels[i+2]= color(constrain(brightness(img.pixels[i+2])+err,0,255)); img.pixels[i+width-1]= color(constrain(brightness(img.pixels[i+width-1])+err,0,255)); img.pixels[i+width]= color(constrain(brightness(img.pixels[i+width])+err,0,255)); img.pixels[i+width+1]= color(constrain(brightness(img.pixels[i+width+1])+err,0,255)); img.pixels[i+(2*width)]= color(constrain(brightness(img.pixels[i+(2*width)])+err,0,255)); */ } } updatePixels(); } void noiseDither(PImage img) { img.loadPixels(); loadPixels(); color c1 = color(0,0,0); color c2 = color(255,255,255); for (int i=0; i<(width*height); ++i) { if ( brightness(img.pixels[i])rastr[i % rsize][j % rsize] ) { pixels[ind]=color(255); } else { pixels[ind]=color(0); } */ pixels[ind]=rastr[i % rsize][j % rsize]*16; } } updatePixels(); } int UP=0; int RIGHT=1; int DOWN=2; int LEFT=3; int xx=0; int yy=0; int step=0; float err=0; float errkoef=(31.0/32.0); void hilbertstep(int xx, int yy) { if ((xx128) { pixels[yy*width+xx]=color(255); err-=255; } else { pixels[yy*width+xx]=color(0); } err*=errkoef; } } void move( int where ) { int ox=xx; int oy=yy; switch ( where ) { case 0: yy--; break; case 1: xx++; break; case 2: yy++; break; case 3: xx--; break; } step++; step=step%255; stroke(step); hilbertstep(xx,yy); } void hilbert(int level) { img.loadPixels(); loadPixels(); hilbert_level( level, 0); updatePixels(); } void hilbert_level(int level,int direction) { stroke(255); strokeWeight(1); if (level==1) { switch (direction) { case 3: move(1); /* move() could draw a line in... */ move(2); /* ...the indicated direction */ move(3); break; case 1: move(3); move(0); move(1); break; case 0: move(2); move(1); move(0); break; case 2: move(0); move(3); move(2); break; } /* switch */ } else { switch (direction) { case 3: hilbert_level(level-1,UP); move(RIGHT); hilbert_level(level-1,LEFT); move(DOWN); hilbert_level(level-1,LEFT); move(LEFT); hilbert_level(level-1,DOWN); break; case 1: hilbert_level(level-1,DOWN); move(LEFT); hilbert_level(level-1,RIGHT); move(UP); hilbert_level(level-1,RIGHT); move(RIGHT); hilbert_level(level-1,UP); break; case 0: hilbert_level(level-1,LEFT); move(DOWN); hilbert_level(level-1,UP); move(RIGHT); hilbert_level(level-1,UP); move(UP); hilbert_level(level-1,RIGHT); break; case 2: hilbert_level(level-1,RIGHT); move(UP); hilbert_level(level-1,DOWN); move(LEFT); hilbert_level(level-1,DOWN); move(DOWN); hilbert_level(level-1,LEFT); break; } /* switch */ } /* if */ } void keyPressed() { background(255,0,0); xx=0;yy=0; String s=""; switch (key) { case 'z': case 'Z': regularDither(img,2); s = "regular dither - 2 colors"; break; case 'm': case 'M': copyGray(img); s = "gray(image)"; break; case 'q': case 'Q': errkoef=1; hilbert(10); s = "hilbert sfc, color is important, k=1"; break; case 'w': case 'W': errkoef=(31.0/32.0); hilbert(10); s = "hilbert sfc, optimal, k=31/32"; break; case 'e': case 'E': errkoef=(28.0/32.0); hilbert(10); s = "hilbert sfc, shape is important, k=7/8"; break; case 'r': case 'R': errkoef=(24.0/32.0); hilbert(10); s = "hilbert sfc, shape is important, k=2/3"; break; case 't': case 'T': errkoef=(16.0/32.0); hilbert(10); s = "hilbert sfc, shape is important, k=1/2"; break; case 'y': case 'Y': errkoef=(8.0/32.0); hilbert(10); s = "hilbert sfc, shape is important, k=1/4"; break; case 'u': case 'U': errkoef=(4.0/32.0); hilbert(10); s = "hilbert sfc, shape prevails, k=1/8"; break; case 'i': case 'I': errkoef=0; hilbert(10); s = "hilbert sfc, shape prevails, k=0"; break; case 'p': case 'P': noiseDither(img); s = "noise diffusion"; break; case 'o': case 'O': noiseDither4col(img); s = "4 color noise diffusion"; break; case 'a': case 'A': noiseDitherNcol(img,2); s = "noise diffusion 2 colors"; break; case 's': case 'S': noiseDitherNcol(img,3); s = "noise diffusion 3 colors"; break; case 'd': case 'D': noiseDitherNcol(img,4); s = "noise diffusion 4 colors"; break; case 'f': case 'F': noiseDitherNcol(img,8); s = "noise diffusion 8 colors"; break; case 'g': case 'G': noiseDitherNcol(img,16); s = "noise diffusion 16 colors"; break; case 'h': case 'H': noiseDitherNcol(img,32); s = "noise diffusion 32 colors"; break; case 'j': case 'J': noiseDitherNcol(img,64); s = "noise diffusion 64 colors"; break; case 'k': case 'K': atkinsonDither(img); s = "Bill Atkinson's dither"; break; case 'l': case 'L': atkinsonColorDither(img); s = "Bill Atkinson's color dither"; break; case ' ': img.copy(bg,0,0,bg.width,bg.height,0,0,width,height); image(img,0,0); break; } fill(0,120); text(s, 20, height-30, 470, 70); fill(0); text(s, 19, height-31, 470, 70); fill(255); text(s, 18, height-32, 470, 70); } void draw() { }