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