Expand preview and center dominant sampling
This commit is contained in:
+8
-4
@@ -214,7 +214,9 @@ function sampleDominantRegions(
|
||||
cropX: number,
|
||||
cropY: number,
|
||||
) {
|
||||
const scale = 4;
|
||||
// An odd sampling grid has a real center point and avoids directional ties
|
||||
// at object boundaries (the former 4x4 grid favored one side on exact ties).
|
||||
const scale = 5;
|
||||
const sample = document.createElement("canvas");
|
||||
sample.width = width * scale;
|
||||
sample.height = height * scale;
|
||||
@@ -228,7 +230,7 @@ function sampleDominantRegions(
|
||||
|
||||
for (let row = 0; row < height; row++) {
|
||||
for (let column = 0; column < width; column++) {
|
||||
const groups: Array<{ count: number; lab: Oklab; samples: Array<{ rgb: [number, number, number]; lab: Oklab }> }> = [];
|
||||
const groups: Array<{ count: number; lab: Oklab; samples: Array<{ rgb: [number, number, number]; lab: Oklab }>; containsCenter: boolean }> = [];
|
||||
let transparentCount = 0;
|
||||
for (let offsetY = 0; offsetY < scale; offsetY++) {
|
||||
for (let offsetX = 0; offsetX < scale; offsetX++) {
|
||||
@@ -239,6 +241,7 @@ function sampleDominantRegions(
|
||||
}
|
||||
const rgb: [number, number, number] = [source[sourceIndex], source[sourceIndex + 1], source[sourceIndex + 2]];
|
||||
const lab = rgbToOklab(rgb);
|
||||
const isCenter = offsetX === Math.floor(scale / 2) && offsetY === Math.floor(scale / 2);
|
||||
let closest: (typeof groups)[number] | undefined;
|
||||
let closestDistance = Number.POSITIVE_INFINITY;
|
||||
for (const group of groups) {
|
||||
@@ -253,8 +256,9 @@ function sampleDominantRegions(
|
||||
closest.lab = closest.lab.map((value, channel) => (value * closest.count + lab[channel]) / total) as Oklab;
|
||||
closest.count = total;
|
||||
closest.samples.push({ rgb, lab });
|
||||
closest.containsCenter ||= isCenter;
|
||||
} else {
|
||||
groups.push({ count: 1, lab: [...lab], samples: [{ rgb, lab }] });
|
||||
groups.push({ count: 1, lab: [...lab], samples: [{ rgb, lab }], containsCenter: isCenter });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,7 +268,7 @@ function sampleDominantRegions(
|
||||
confidence[row * width + column] = transparentCount / (scale * scale);
|
||||
continue;
|
||||
}
|
||||
const dominant = groups.sort((a, b) => b.count - a.count)[0];
|
||||
const dominant = groups.sort((a, b) => b.count - a.count || Number(b.containsCenter) - Number(a.containsCenter))[0];
|
||||
const representative = dominant.samples.reduce((best, current) =>
|
||||
oklabDistance(current.lab, dominant.lab) < oklabDistance(best.lab, dominant.lab) ? current : best,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user