{
const context = DOM.context2d(imageWidth, imageHeight, 1);
context.drawImage(image, 0, 0, imageWidth, imageHeight);
context.canvas.style.width = "400px";
context.canvas.style.border = "1px solid black";
const grid = getCells(100).map((cell) => {
const { x, y, width, height } = cell;
const pixels = getPixels2({
context,
x,
y,
width,
height
});
const meanLightness = d3.mean(pixels, (d) => d.lightness);
return {
...cell,
meanLightness
};
});
const columns = d3.max(grid, (d) => d.column) + 1;
const rows = d3.max(grid, (d) => d.row) + 1;
const xScale = d3.scaleLinear([0, columns], [0, imageWidth]);
const yScale = d3.scaleLinear([0, rows], [0, imageHeight]);
const contours = d3
.contours()
.thresholds(d3.range(0, 300, 20))
.size([columns, rows])(grid.map((d) => d.meanLightness));
contours.forEach(({ coordinates }) => {
coordinates.forEach((lineStrings) => {
lineStrings.forEach((points) => {
points.forEach((point) => {
point[0] = xScale(point[0]);
point[1] = yScale(point[1]);
});
});
});
});
mutable contours_ = contours;
const contourPaths = contours
.map((geoJSON) => d3.geoPath()(geoJSON))
.filter((d) => d)
.map(
(pathDef) => htl.svg`<path fill="none" stroke="black" d=${pathDef} />`
);
return htl.html`
<svg viewBox="0 0 ${imageWidth} ${imageHeight}" style="width: 400px; border: 1px dashed red;">
${contourPaths}
</svg>
`;
}