52 lines
2.0 KiB
JavaScript
52 lines
2.0 KiB
JavaScript
import fs from "node:fs";
|
|
|
|
const meta = JSON.parse(fs.readFileSync("clip.rgba.json", "utf8"));
|
|
const px = fs.readFileSync("clip.rgba");
|
|
const { w, ch, h } = meta;
|
|
const at = (x, y) => { const o = (y * w + x) * ch; return [px[o], px[o + 1], px[o + 2]]; };
|
|
const D = (a, b) => Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]) + Math.abs(a[2] - b[2]);
|
|
const hex = (c) => c.map((v) => v.toString(16).padStart(2, "0")).join("");
|
|
|
|
const Y0 = Number(process.argv[2] || 372);
|
|
const Y1 = Number(process.argv[3] || 500);
|
|
|
|
const isInk = (x, y) => {
|
|
const c = at(x, y);
|
|
if (D(c, [255, 255, 255]) <= 20) return false;
|
|
if (D(c, [227, 234, 246]) <= 14) return false;
|
|
if (D(c, [230, 235, 244]) <= 14) return false;
|
|
if (D(c, [236, 237, 243]) <= 10) return false;
|
|
return true;
|
|
};
|
|
|
|
const seen = new Uint8Array(w * h);
|
|
const comps = [];
|
|
for (let y = Y0; y < Y1; y++) {
|
|
for (let x = 0; x < w; x++) {
|
|
if (seen[y * w + x] || !isInk(x, y)) continue;
|
|
let minX = x, maxX = x, minY = y, maxY = y, n = 0, sr = 0, sg = 0, sb = 0;
|
|
const st = [x, y];
|
|
seen[y * w + x] = 1;
|
|
while (st.length) {
|
|
const cy = st.pop(), cx = st.pop();
|
|
n++;
|
|
const c = at(cx, cy);
|
|
sr += c[0]; sg += c[1]; sb += c[2];
|
|
if (cx < minX) minX = cx; if (cx > maxX) maxX = cx;
|
|
if (cy < minY) minY = cy; if (cy > maxY) maxY = cy;
|
|
for (const [dx, dy] of [[1, 0], [-1, 0], [0, 1], [0, -1]]) {
|
|
const nx = cx + dx, ny = cy + dy;
|
|
if (nx < 0 || nx >= w || ny < Y0 || ny >= Y1) continue;
|
|
if (!seen[ny * w + nx] && isInk(nx, ny)) { seen[ny * w + nx] = 1; st.push(nx, ny); }
|
|
}
|
|
}
|
|
if (n > 25) comps.push({ x: minX, y: minY, w: maxX - minX + 1, h: maxY - minY + 1, n, c: [Math.round(sr / n), Math.round(sg / n), Math.round(sb / n)] });
|
|
}
|
|
}
|
|
|
|
comps.sort((a, b) => a.x - b.x);
|
|
console.log(`区域 y${Y0}-${Y1} 内「墨迹」连通域 ${comps.length} 个(按 x 排序,CSS 坐标):`);
|
|
for (const b of comps) {
|
|
console.log(` x${Math.round(b.x / 2)} y${Math.round(b.y / 2)} ${Math.round(b.w / 2)}x${Math.round(b.h / 2)} px${b.n} avg#${hex(b.c)}`);
|
|
}
|