Mod: Coding Challenge #90: Floyd-Steinberg Dithering
チュートリアルではFloyd-Steinbergのディザを生成するアルゴリズムを使っているが,書き換えたプログラムでは便宜上16を4つのランダムな数字をつかって表すやり方でディザを作ってみている.
コード
import processing.pdf.*; import java.util.Calendar; PImage cat; boolean savePDF; void setup() { size(1024, 512); } void draw() { if (savePDF) { beginRecord(PDF, timestamp() + ".pdf"); } cat = loadImage("cat.jpg"); cat.filter(GRAY); background(255, 255, 255); image(cat, 0, 0); int n1 = max((int)random(8), 1); int n2 = max((int)random(16-n1), 1); int n3 = max((int)random(16-n1-n2), 1); int n4 = 16-n1-n2-n3; cat.loadPixels(); for (int y = 0; y < cat.height-1; y++) { for (int x = 0; x < cat.width-1; x++) { color pix = cat.pixels[index(x, y)]; float oldR = red(pix); float oldG = green(pix); float oldB = blue(pix); int factor = 1; int newR = round(factor * oldR / 255) * (255 / factor); int newG = round(factor * oldG / 255) * (255 / factor); int newB = round(factor * oldB / 255) * (255 / factor); cat.pixels[index(x, y)] = color(newR, newG, newB); float errR = oldR - newR; float errG = oldG - newG; float errB = oldB - newB; int index = index(x+1, y); color c = cat.pixels[index]; float r = red(c); float g = green(c); float b = blue(c); r = r + errR * n1/16.0; g = g + errG * n1/16.0; b = b + errB * n1/16.0; cat.pixels[index] = color(r, g, b); index = index(x-1, y+1); c = cat.pixels[index]; r = red(c); g = green(c); b = blue(c); r = r + errR * n2/16.0; g = g + errG * n2/16.0; b = b + errB * n2/16.0; cat.pixels[index] = color(r, g, b); index = index(x, y+1); c = cat.pixels[index]; r = red(c); g = green(c); b = blue(c); r = r + errR * n3/16.0; g = g + errG * n3/16.0; b = b + errB * n3/16.0; cat.pixels[index] = color(r, g, b); index = index(x+1, y+1); c = cat.pixels[index]; r = red(c); g = green(c); b = blue(c); r = r + errR * n4/16.0; g = g + errG * n4/16.0; b = b + errB * n4/16.0; cat.pixels[index] = color(r, g, b); } } cat.updatePixels(); image(cat, 512, 0); noLoop(); if (savePDF) { endRecord(); } } void mousePressed() { redraw(); } void keyPressed() { if (key == 's' || key == 'S') saveFrame(timestamp()+"_##.png"); if (key == 'p' || key == 'P') savePDF = true; } String timestamp() { Calendar now = Calendar.getInstance(); return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now); } int index(int x, int y) { return x + y * cat.width; }