// Repaint the cream moon discs (and their tan rim) with the background colour, in the given x-ranges only. const sharp = require("module").createRequire("/home/ubuntu/kalki-cli/projects/mybazaar-web/package.json")("sharp"); const [, , input, output, ...ranges] = process.argv; (async () => { const { data, info } = await sharp(input).removeAlpha().raw().toBuffer({ resolveWithObject: true }); const { width, height } = info; const spans = ranges.map((r) => r.split("-").map(Number)); const inSpan = (x) => spans.some(([a, b]) => x >= a && x <= b); const bg = [data[0], data[1], data[2]]; const warm = (i) => data[i] - data[i + 2]; const mask = new Uint8Array(width * height); for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) { const i = (y * width + x) * 3; if (inSpan(x) && warm(i) > 28 && data[i] > 170) mask[y * width + x] = 1; } // Grow the mask four times over faintly warm pixels: the anti-aliased rim is up to four pixels wide. for (let pass = 0; pass < 4; pass++) { const grow = mask.slice(); for (let y = 1; y < height - 1; y++) for (let x = 1; x < width - 1; x++) { const p = y * width + x; if (mask[p] || !inSpan(x)) continue; const i = p * 3; if (warm(i) > 3 && data[i] > 150 && (mask[p - 1] || mask[p + 1] || mask[p - width] || mask[p + width])) grow[p] = 1; } mask.set(grow); } // One flat fill in the corner colour, which is exactly what remove-background samples and clears. let n = 0; for (let p = 0; p < mask.length; p++) if (mask[p]) { data.set(bg, p * 3); n++; } await sharp(data, { raw: { width, height, channels: 3 } }).png().toFile(output); console.log(`repainted ${n} px`); })();