Published
Edited
Jan 20, 2021
7 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
floydsteinberg = {
//*

function diffuseError(mydata, r, c, error, factor){
var idx = rowcol2index(r, c, w, h);
mydata[idx+0] = Math.max(Math.min(mydata[idx+0] + factor*error.r,255),0);
mydata[idx+1] = Math.max(Math.min(mydata[idx+1] + factor*error.g,255),0);
mydata[idx+2] = Math.max(Math.min(mydata[idx+2] + factor*error.b,255),0);
return(mydata)
}
//var w = mywidth;
//var h = Math.floor(image.height*mywidth/image.width);
var context = DOM.context2d(w, h);
var imgData = context.createImageData(w, h);
var dithered = [];
for (var ii=0; ii<raw_rgba.length; ii++){
imgData.data[ii] = raw_rgba[ii];
dithered.push(raw_rgba[ii]);
}

var paletteIDs = [];
for (var ii=0; ii<dithered.length; ii+=4){
var RC = index2rowcol(ii, w, h);
var myRow = RC.r;
var myCol = RC.c;
// oldpixel := pixel[x][y]
var thisRawColor = d3.rgb(dithered[ii+0],
dithered[ii+1],
dithered[ii+2]);
var thisOrigColor = d3.rgb(raw_rgba[ii+0],
raw_rgba[ii+1],
raw_rgba[ii+2]);

if(starMatrix[myRow][myCol]){ //
var closeColorID = -1;
var thisPalleteColor = d3.rgb(starColor);
}else{
if(Math.random()<pRand(myRow)){
var closeColorID = FindClosestColorIDFrom(colorPalette, thisOrigColor);
}else{
var closeColorID = FindClosestColorIDFrom(colorPalette, thisRawColor);
}
var thisPalleteColor = d3.rgb(colorPalette[closeColorID]);
}
paletteIDs.push(closeColorID)
dithered[ii+0] = thisPalleteColor.r;
dithered[ii+1] = thisPalleteColor.g;
dithered[ii+2] = thisPalleteColor.b;
dithered[ii+3] = 255;
// quant_error := oldpixel - newpixel
var quant_error = {r:(thisRawColor.r-thisPalleteColor.r),
g:(thisRawColor.g-thisPalleteColor.g),
b:(thisRawColor.b-thisPalleteColor.b)}

if ((myRow<(h-2))&(myCol<(w-2))&(myCol>(1))){
dithered = diffuseError(dithered, myRow+0, myCol+1, quant_error, 7/48); // this is so f***ing cool
dithered = diffuseError(dithered, myRow+0, myCol+2, quant_error, 5/48); //
dithered = diffuseError(dithered, myRow+1, myCol-2, quant_error, 3/48); // basically we take the error
dithered = diffuseError(dithered, myRow+1, myCol-1, quant_error, 5/48); // in how close we came
dithered = diffuseError(dithered, myRow+1, myCol+0, quant_error, 7/48); // to approximating true color
dithered = diffuseError(dithered, myRow+1, myCol+1, quant_error, 5/48); // and we add
dithered = diffuseError(dithered, myRow+1, myCol+2, quant_error, 3/48); // (a portion of) that delta
dithered = diffuseError(dithered, myRow+2, myCol-2, quant_error, 1/48); // to the nearby pixels
dithered = diffuseError(dithered, myRow+2, myCol-1, quant_error, 3/48); //
dithered = diffuseError(dithered, myRow+2, myCol+0, quant_error, 5/48); // how cool is that
dithered = diffuseError(dithered, myRow+2, myCol+1, quant_error, 3/48); //
dithered = diffuseError(dithered, myRow+2, myCol+2, quant_error, 1/48); // and it works
}
} // end of pixel by pixel FOR loop
//
for (var ii=0; ii<dithered.length; ii++){
imgData.data[ii] = dithered[ii];
}
return({rgba: imgData.data, paletteData: paletteIDs})
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
d3 = require("d3")
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more