WIP trying to redo some stuff
This commit is contained in:
parent
bc354d9f05
commit
801c6ee0a6
1 changed files with 28 additions and 40 deletions
|
@ -110,16 +110,10 @@ class RGB {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
magnitude() {
|
magnitude2() {
|
||||||
return Math.sqrt(
|
return this.r * this.r +
|
||||||
this.r * this.r +
|
|
||||||
this.g * this.g +
|
this.g * this.g +
|
||||||
this.b * this.b
|
this.b * this.b;
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
distance(other) {
|
|
||||||
return this.difference(other).magnitude();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,6 +431,7 @@ function decimate(input, palette, n, inputError) {
|
||||||
|
|
||||||
let output = new Uint8Array(width);
|
let output = new Uint8Array(width);
|
||||||
let popularity = new Int32Array(width);
|
let popularity = new Int32Array(width);
|
||||||
|
let distance2 = 0;
|
||||||
|
|
||||||
let nextError = new RGB(0, 0, 0);
|
let nextError = new RGB(0, 0, 0);
|
||||||
|
|
||||||
|
@ -451,7 +446,7 @@ function decimate(input, palette, n, inputError) {
|
||||||
|
|
||||||
for (let i = 0; i < palette.length; i++) {
|
for (let i = 0; i < palette.length; i++) {
|
||||||
let diff = rgb.difference(atariRGB[palette[i]]);
|
let diff = rgb.difference(atariRGB[palette[i]]);
|
||||||
let dist = diff.magnitude();
|
let dist = diff.magnitude2();
|
||||||
if (dist < shortest) {
|
if (dist < shortest) {
|
||||||
nextError = diff;
|
nextError = diff;
|
||||||
shortest = dist;
|
shortest = dist;
|
||||||
|
@ -472,15 +467,16 @@ function decimate(input, palette, n, inputError) {
|
||||||
error.next[x]?.inc(double);
|
error.next[x]?.inc(double);
|
||||||
error.next[x + 1]?.inc(double);
|
error.next[x + 1]?.inc(double);
|
||||||
|
|
||||||
// 442 is the 3d distance across the rgb cube
|
// just store the distance2
|
||||||
//fitness[x] = 442 - (nextError.magnitude());
|
let mag2 = nextError.magnitude2();
|
||||||
//fitness[x] = 442 / (442 - nextError.magnitude());
|
fitness[x] = mag2;
|
||||||
fitness[x] = 255 / (256 - Math.max(0, nextError.r, nextError.g, nextError.b));
|
distance2 += mag2;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
output,
|
output,
|
||||||
palette,
|
palette,
|
||||||
fitness,
|
fitness,
|
||||||
|
distance2,
|
||||||
popularity,
|
popularity,
|
||||||
error: error.next
|
error: error.next
|
||||||
};
|
};
|
||||||
|
@ -510,43 +506,34 @@ function decimate(input, palette, n, inputError) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (decimated.length > n) {
|
while (decimated.length > n) {
|
||||||
let {popularity, fitness, output} = dither(decimated);
|
// Try dithering to every possible subset
|
||||||
|
// See which has the worst overall fit and drop it
|
||||||
// Try dropping least used color on each iteration
|
let farthest = -1;
|
||||||
let least = Infinity;
|
let worstIndex = -1;
|
||||||
let pick = -1;
|
for (let i = 0; i < decimated.length; i++) {
|
||||||
for (let i = 1; i < decimated.length; i++) {
|
|
||||||
let color = decimated[i];
|
let color = decimated[i];
|
||||||
if (keepers[color]) {
|
if (keepers[color]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let coolFactor = fitness[i] * popularity[i];
|
let shorter = decimated.filter((x) => x != i);
|
||||||
//let coolFactor = popularity[i];
|
let {distance2} = dither(shorter);
|
||||||
//let coolFactor = (fitness[i] ** 2) * popularity[i];
|
|
||||||
|
|
||||||
if (coolFactor < least) {
|
if (distance2 >= farthest) {
|
||||||
pick = i;
|
farthest = distance2;
|
||||||
least = coolFactor;
|
worstIndex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.log(`worstIndex ${worstIndex} farthest ${farthest}`);
|
||||||
let last = decimated.length;
|
let foo = decimated.length;
|
||||||
decimated = decimated.filter((color, i) => {
|
decimated.splice(worstIndex, 1);
|
||||||
if (keepers[color]) {
|
//console.log(decimated.length);
|
||||||
return true;
|
if (decimated.length == foo) {
|
||||||
}
|
|
||||||
if (i == pick) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (decimated.length == last && last > n) {
|
|
||||||
console.log(decimated);
|
|
||||||
throw new Error('this should not happen');
|
throw new Error('this should not happen');
|
||||||
}
|
}
|
||||||
|
//console.log('n ', decimated);
|
||||||
}
|
}
|
||||||
|
console.log('end', decimated);
|
||||||
|
|
||||||
// Palette fits
|
// Palette fits
|
||||||
return dither(decimated);
|
return dither(decimated);
|
||||||
|
@ -639,6 +626,7 @@ async function convert(source, nbits) {
|
||||||
|
|
||||||
let lines = [];
|
let lines = [];
|
||||||
for (let y = 0; y < height; y++) {
|
for (let y = 0; y < height; y++) {
|
||||||
|
console.log(`y ${y}`);
|
||||||
let error = lines[y - 1]?.error;
|
let error = lines[y - 1]?.error;
|
||||||
let inputLine = input.slice(y * width, (y + 1) * width);
|
let inputLine = input.slice(y * width, (y + 1) * width);
|
||||||
let line = decimate(inputLine, allColors, 4, error);
|
let line = decimate(inputLine, allColors, 4, error);
|
||||||
|
|
Loading…
Reference in a new issue