Public
Edited
Aug 6, 2024
Importers
1 star
Insert cell
Insert cell
/** Renders image applying a list of processors to its pixels.
* @param image image HTML image instance.
* @param {...function} processors Functions that takes and returns pixels.
* @usage renderImage(image, ...processors)
*/
renderImage = (image, ...processors) => {
const getPixels = function (img) {
const c = document.createElement("canvas");
c.width = img.width > 1000 ? 1000 : img.width;
c.height = img.width > 1000 ? (1000 / img.width) * img.height : img.height;
const ctx = c.getContext("2d");
ctx.drawImage(img, 0, 0, c.width, c.height);
return {
pixels: ctx.getImageData(0, 0, c.width, c.height),
context: ctx,
canvas: c
};
};
const pipe = (fns) => (arg) => fns.reduce((acc, fn) => fn(acc), arg);

const { canvas, context, pixels } = getPixels(image);
context.putImageData(pipe(processors)(pixels), 0, 0);
return canvas;
}
Insert cell
math = {
// Functions copied from P5js
return {
sin: Math.sin,
abs: Math.abs,
cos: Math.cos,
random(max) {
return Math.random() * max;
},
constrain(n, low, high) {
return Math.max(Math.min(n, high), low);
},
randomGaussian(mean, sd) {
let y1, y2, x1, x2, w;
do {
x1 = this.random(2) - 1;
x2 = this.random(2) - 1;
w = x1 * x1 + x2 * x2;
} while (w >= 1);
w = Math.sqrt((-2 * Math.log(w)) / w);
y1 = x1 * w;
y2 = x2 * w;

const m = mean || 0;
const s = sd || 1;
return y1 * s + m;
},
map(n, start1, stop1, start2, stop2, withinBounds) {
const newval =
((n - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
if (!withinBounds) {
return newval;
}
if (start2 < stop2) {
return this.constrain(newval, start2, stop2);
} else {
return this.constrain(newval, stop2, start2);
}
},
range(length) {
return Array.from({ length }).map((x, i) => i);
}
};
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more