Files
work-leave-service/png-bar.mjs
T
wanghu 25147ec74e
build / build-push (push) Successful in 50s
commit
2026-10-10 15:42:52 +08:00

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)}`);
}