some oldbits

This commit is contained in:
Brooke Vibber 2023-03-19 18:22:33 -07:00
parent 9a93e7341f
commit 9826a90e02

View file

@ -426,7 +426,7 @@ function decimate(input, palette, n, inputError, y) {
// Apply dithering with given palette and collect color usage stats // Apply dithering with given palette and collect color usage stats
let dither = (palette) => { let dither = (palette) => {
let fitness = new Float64Array(palette.length); let fitness = new Float64Array(width);
let error = { let error = {
cur: [], cur: [],
next: [], next: [],
@ -476,10 +476,12 @@ function decimate(input, palette, n, inputError, y) {
let mag = nextError.magnitude(); let mag = nextError.magnitude();
fitness[x] = maxDist / mag; fitness[x] = maxDist / mag;
// 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(); let mag2 = nextError.magnitude2();
//fitness[x] = mag2;
distance2 += mag2; distance2 += mag2;
} }
return { return {
@ -509,11 +511,12 @@ function decimate(input, palette, n, inputError, y) {
//reserved = [0, 5, 10, 15]; // grayscale //reserved = [0, 5, 10, 15]; // grayscale
//reserved = [0, 0x48, 0x78, 15]; // vaporwave //reserved = [0, 0x48, 0x78, 15]; // vaporwave
//reserved = [0, 0x3c, 0x78, 15]; // red/blue/white //reserved = [0, 0x3c, 0x78, 15]; // red/blue/white
/* /*
if (( y & 1 ) === 0) { if (( y & 1 ) === 0) {
reserved = [0, 0x3c, 0x1a, 15]; // red/yellow/white reserved = [0, 0x3c, 0x1e, 15]; // red/yellow/white
} else { } else {
reserved = [0, 0x76, 0x9a, 15]; // blue/cyan/white reserved = [0, 0x76, 0x9e, 0xb8]; // blue/cyan/green
} }
*/ */
@ -553,7 +556,8 @@ function decimate(input, palette, n, inputError, y) {
a = a.sort((a, b) => b.count - a.count); a = a.sort((a, b) => b.count - a.count);
a = a.map(({hue}) => hue); a = a.map(({hue}) => hue);
a = a.filter((color) => !keepers[color]); a = a.filter((color) => !keepers[color]);
a = a.slice(0, n - reserved.length); //a = a.slice(0, n - reserved.length);
a = a.slice(0, decimated.length - 1 - reserved.length);
a = a.map((hue) => (hue << 4) | lumas[hue]); a = a.map((hue) => (hue << 4) | lumas[hue]);
a = a.sort((a, b) => a - b); a = a.sort((a, b) => a - b);
@ -564,20 +568,64 @@ function decimate(input, palette, n, inputError, y) {
// popularity? not really working right // popularity? not really working right
// first, dither to the total atari palette // first, dither to the total atari palette
/*
while (decimated.length > n) { while (decimated.length > n) {
let {popularity, fitness} = dither(decimated);
// temporarily strip the reserved items
//console.log(y); //console.log(y);
let {popularity} = dither(decimated);
let a = decimated; let a = decimated;
// temporarily strip the reserved items
a = a.filter((color) => !keepers[color]); a = a.filter((color) => !keepers[color]);
a = a.sort((a, b) => popularity[b] - popularity[a]); a = a.sort((a, b) => popularity[b] - popularity[a]);
//a = a.slice(0, n - reserved.length);
a = reserved.concat(a); a = reserved.concat(a);
decimated = a.slice(0, decimated.length - 1); decimated = a.slice(0, n);
//console.log(decimated); //console.log(decimated);
} }
//console.log('end', decimated); //console.log('end', decimated);
*/
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++) {
//let coolFactor = popularity[i];
let coolFactor = 0;
if (popularity[i]) {
for (let x = 0; x < width; x++) {
if (output[x] == i) {
// Scale up the scoring for close matches to prioritize
// color accuracy over raw linear usage.
//coolFactor += (fitness[x] ** 2);
coolFactor += (fitness[x] ** 4);
}
}
}
if (coolFactor < least) {
pick = i;
least = coolFactor;
}
decimated = decimated.filter((color, i) => {
if (i == 0) {
return true;
}
if (i == pick) {
return false;
}
// Also drop any non-black unused colors to save trouble.
// However -- this may change dither results.
// Try this with/without later.
if (popularity[i] == 0) {
return false;
}
return true;
});
}
}
// Palette fits // Palette fits
return dither(decimated); return dither(decimated);
} }
@ -845,6 +893,7 @@ async function saveImage(width, height, lines, dest) {
resolve(image); resolve(image);
}); });
}); });
await image.resize(Math.round(width2 * 2 / 1.2), height * 2);
await image.writeAsync(dest); await image.writeAsync(dest);
} }