Gray value of each engraving cell
32-bit in partThe average gray of the picture's pixels under each cell of the engraving grid.
gray = Σ w × pixel ÷ Σ w, w = overlap area of pixel and cell
The weighted sum is formed in 64-bit and then stored in a Float32Array, which keeps about 7 digits. The stored value is what the burn level is decided from.
export function resample(gray, pw, ph, cols, rows) {
const out = new Float32Array(cols * rows);
if (!(pw > 0 && ph > 0 && cols > 0 && rows > 0)) return out;
const sx = pw / cols, sy = ph / rows;
for (let r = 0; r < rows; r++) {
const y0 = r * sy, y1 = (r + 1) * sy;
for (let c = 0; c < cols; c++) {
const x0 = c * sx, x1 = (c + 1) * sx;
if (sx <= 1 && sy <= 1) { out[r * cols + c] = gray[Math.min(ph - 1, Math.floor((y0 + y1) / 2)) * pw + Math.min(pw - 1, Math.floor((x0 + x1) / 2))]; continue; }
let sum = 0, wsum = 0;
for (let j = Math.floor(y0); j < Math.min(ph, Math.ceil(y1)); j++) {
const wy = Math.min(y1, j + 1) - Math.max(y0, j);
for (let i = Math.floor(x0); i < Math.min(pw, Math.ceil(x1)); i++) {
const w = wy * (Math.min(x1, i + 1) - Math.max(x0, i));
sum += w * gray[j * pw + i]; wsum += w;
}
}
out[r * cols + c] = wsum > 0 ? sum / wsum : 255;
}
}
return out;
}