xxxxxxxxxx
114
const BLACK_AND_WHITE = false;
const WITH_PALETTE = true;
const PALETTE = [
[0, 0, 0],
[0, 0, 125],
[125, 0, 255],
[255, 125, 125],
[255, 125, 0],
[255, 125, 125],
[255, 125, 255],
[255, 255, 255],
]
let capture;
let bitDepthSlider;
let resolutionSlider;
function setup() {
createCanvas(200, 200);
colorMode(RGB, 1);
capture = createCapture(VIDEO);
capture.hide();
bitDepthSlider = createSlider(1, 8, 8);
bitDepthSlider.position(10, 10);
bitDepthSlider.style('width', '100px');
resolutionSlider = createSlider(10, windowHeight, 200);
resolutionSlider.position(10, 30);
resolutionSlider.style('width', '100px');
resolutionSlider.input(windowResized); // event handler (I would've called it: onInput)
windowResized();
}
// press 1 for screenshot
function keyPressed() {
if (keyCode === 49) {
const size = resolutionSlider.value();
resizeCanvas(size, size, WEBGL);
draw();
save();
windowResized();
}
}
function windowResized() {
const winRat = windowHeight / windowWidth;
const res = resolutionSlider.value();
resizeCanvas(res, floor(res * winRat));
}
function draw() {
background(0);
strokeWeight(1);
for (let x=0; x<width; x++) { // background gradient
stroke(x / width);
line(x, 0, x, height);
}
const {w, h} = contain(capture.width, capture.height, width, height); // letterbox
const x = (width - w) / 2;
const y = (height - h) / 2;
image(capture,x, y, w, h); // center webcam in square
floydSteinbergDither(bitDepthSlider.value());
}
function contain(w, h, fw, fh) {
const rat = w/h;
const fRat = fw/fh;
if (rat > fRat)
return { w: fw, h: fw / rat }
return { w: fh * rat, h: fh }
}
function floydSteinbergDither(bitDepth) {
loadPixels();
for (let i=0; i<pixels.length; i++) {
if (i % 4 == 3) // don't change alpha value
continue;
if (BLACK_AND_WHITE || WITH_PALETTE) // set green and blue equal to red (grayscale)
if (i % 4 > 0) {
if (BLACK_AND_WHITE)
pixels[i] = pixels[i-1];
continue;
}
const oldPixel = pixels[i];
const div = (256 / bitDepth);
const newPixel = round(oldPixel / div) * div;
const error = oldPixel - newPixel;
pixels[i + 4] += error * 7 / 16; // x + 1, y
pixels[i - 4 + width * 4] += error * 3 / 16; // x - 1, y + 1
pixels[i + width * 4] += error * 5 / 16; // x , y + 1
pixels[i + 4 + width * 4] += error * 1 / 16; // x + 1, y + 1
if (!WITH_PALETTE) {
pixels[i] = newPixel;
}else{
const index = floor((PALETTE.length - 1) * (newPixel / 256));
const col = PALETTE[index];
pixels[i] = col[0];
pixels[i+1] = col[1];
pixels[i+2] = col[2];
}
}
updatePixels();
}