Improve transition edge cleanup

This commit is contained in:
wuyanwanwu
2026-08-14 01:29:04 +08:00
parent 8c505a205c
commit daffe4daca
14 changed files with 28 additions and 22 deletions
+11 -5
View File
@@ -360,17 +360,15 @@ function sampleDominantRegions(
function cleanThinTransitionBands(colors: Array<BeadColor | null>, width: number, height: number) {
const cleaned = [...colors];
const usage = new Map<string, number>();
colors.forEach((color) => { if (color) usage.set(color.code, (usage.get(color.code) ?? 0) + 1); });
const maximumTransitionUsage = Math.max(4, Math.ceil(width * height * 0.015));
let changed = 0;
for (let row = 0; row < height; row++) {
for (let column = 0; column < width; column++) {
const index = row * width + column;
const current = colors[index];
if (!current || (usage.get(current.code) ?? 0) > maximumTransitionUsage) continue;
if (!current) continue;
const neighbors = new Map<string, { color: BeadColor; count: number }>();
let sameColorNeighbors = 0;
for (let rowOffset = -1; rowOffset <= 1; rowOffset++) {
for (let columnOffset = -1; columnOffset <= 1; columnOffset++) {
if (rowOffset === 0 && columnOffset === 0) continue;
@@ -378,12 +376,20 @@ function cleanThinTransitionBands(colors: Array<BeadColor | null>, width: number
const neighborColumn = column + columnOffset;
if (neighborRow < 0 || neighborColumn < 0 || neighborRow >= height || neighborColumn >= width) continue;
const neighbor = colors[neighborRow * width + neighborColumn];
if (!neighbor || neighbor.code === current.code) continue;
if (!neighbor) continue;
if (neighbor.code === current.code) {
sameColorNeighbors += 1;
continue;
}
const entry = neighbors.get(neighbor.code) ?? { color: neighbor, count: 0 };
entry.count += 1;
neighbors.set(neighbor.code, entry);
}
}
// A true gradient band has broad same-color support. Anti-aliased edge
// colors form a one-cell-wide chain and have at most two same-color
// neighbors, regardless of how often that edge color occurs globally.
if (sameColorNeighbors > 2) continue;
const candidates = [...neighbors.values()].sort((a, b) => b.count - a.count).slice(0, 3);
let replacement: BeadColor | null = null;
let replacementSupport = 0;