p5.j5
Version:
johnny-five library for p5.js
57 lines (46 loc) • 1.94 kB
JavaScript
/*
from: https://github.com/noopkat/floyd-steinberg
* floyd-steinberg
*
* Using 2D error diffusion formula published by Robert Floyd and Louis Steinberg in 1976
*
* Javascript implementation of Floyd-Steinberg algorithm thanks to Forrest Oliphant @forresto and @meemoo
* via iFramework https://github.com/meemoo/iframework/blob/master/src/nodes/image-monochrome-worker.js
*
* Accepts an object that complies with the HTML5 canvas imageData spec https://developer.mozilla.org/en-US/docs/Web/API/ImageData
* In particular, it makes use of the width, height, and data properties
*
* License: MIT
*/
function floyd_steinberg(image) {
var imageData = image.data;
var imageDataLength = imageData.length;
// console.log('fs image', image, image.width);
var w = image.width;
var lumR = [],
lumG = [],
lumB = [];
var newPixel, err;
for (var i = 0; i < 256; i++) {
lumR[i] = i * 0.299;
lumG[i] = i * 0.587;
lumB[i] = i * 0.110;
}
// Greyscale luminance (sets r pixels to luminance of rgb)
for (var i = 0; i <= imageDataLength; i += 4) {
imageData[i] = Math.floor(lumR[imageData[i]] + lumG[imageData[i+1]] + lumB[imageData[i+2]]);
}
for (var currentPixel = 0; currentPixel <= imageDataLength; currentPixel += 4) {
// threshold for determining current pixel's conversion to a black or white pixel
newPixel = imageData[currentPixel] < 150 ? 0 : 255;
err = Math.floor((imageData[currentPixel] - newPixel) / 23);
imageData[currentPixel + 0 * 1 - 0 ] = newPixel;
imageData[currentPixel + 4 * 1 - 0 ] += err * 7;
imageData[currentPixel + 4 * w - 4 ] += err * 3;
imageData[currentPixel + 4 * w - 0 ] += err * 5;
imageData[currentPixel + 4 * w + 4 ] += err * 1;
// Set g and b values equal to r (effectively greyscales the image fully)
imageData[currentPixel + 1] = imageData[currentPixel + 2] = imageData[currentPixel];
}
return image;
}