wip colors
This commit is contained in:
parent
a8bbcb21cd
commit
365d968448
1 changed files with 66 additions and 10 deletions
|
@ -407,6 +407,18 @@ function decimate(input, palette, n, inputError) {
|
|||
|
||||
let width = input.length;
|
||||
|
||||
let inputPixel = (x, error) => {
|
||||
let rgb = input[x];
|
||||
if (error) {
|
||||
rgb.add(error.cur[x]);
|
||||
}
|
||||
if (inputError) {
|
||||
rgb.inc(inputError[x]);
|
||||
}
|
||||
rgb.cap();
|
||||
return rgb;
|
||||
};
|
||||
|
||||
// Apply dithering with given palette and collect color usage stats
|
||||
let dither = (palette) => {
|
||||
let fitness = new Float64Array(width);
|
||||
|
@ -426,11 +438,7 @@ function decimate(input, palette, n, inputError) {
|
|||
|
||||
// Try dithering with this palette.
|
||||
for (let x = 0; x < width; x++) {
|
||||
let rgb = RGB.add(input[x], error.cur[x]);
|
||||
if (inputError) {
|
||||
rgb.inc(inputError[x]);
|
||||
}
|
||||
rgb.cap();
|
||||
let rgb = inputPixel(x, error);
|
||||
|
||||
// find the closest possible color
|
||||
// @todo consider doing the difference scoring in luminance and hue spaces
|
||||
|
@ -487,16 +495,62 @@ function decimate(input, palette, n, inputError) {
|
|||
//decimated = [0, 0x36, 0x0f, 0x86];
|
||||
|
||||
let reserved = [0]; // black
|
||||
//let reserved = [0, 15]; // black, white
|
||||
//let reserved = [0, 5, 10, 15]; // grayscale
|
||||
//let reserved = [0, 0x48, 0x78, 15]; // vaporwave
|
||||
//let reserved = [0, 0x3c, 0x78, 15]; // red/blue/white
|
||||
//reserved = [0, 15]; // black, white
|
||||
//reserved = [0, 5, 10, 15]; // grayscale
|
||||
//reserved = [0, 0x48, 0x78, 15]; // vaporwave
|
||||
//reserved = [0, 0x3c, 0x78, 15]; // red/blue/white
|
||||
|
||||
let keepers = new Uint8Array(256);
|
||||
for (let i of reserved) {
|
||||
keepers[i & 0xfe] = 1; // drop that 0 luminance bit!
|
||||
}
|
||||
|
||||
|
||||
// not happy with this alt yet
|
||||
|
||||
let colorCount = new Int32Array(256);
|
||||
let hues = new Int32Array(16);
|
||||
let lumaByHue = new Int32Array(16);
|
||||
|
||||
const bestColor = (rgb) => {
|
||||
let best = -1;
|
||||
let closest = Infinity;
|
||||
for (let i = 0; i < 256; i += 2) {
|
||||
let distance = rgb.difference(atariRGB[i]).magnitude();
|
||||
if (distance < closest) {
|
||||
closest = distance;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
};
|
||||
for (let x = 0; x < width; x++ ) {
|
||||
let rgb = inputPixel(x);
|
||||
let i = bestColor(rgb);
|
||||
colorCount[i]++;
|
||||
let hue = i >> 4;
|
||||
hues[hue]++;
|
||||
let luma = i & 0xf;
|
||||
lumaByHue[hue] = Math.max(luma, lumaByHue[hue]);
|
||||
}
|
||||
|
||||
let xhues = [];
|
||||
xhues.push.apply(xhues, hues);
|
||||
|
||||
let popularHues = xhues.map((count, hue) => {return {count, hue}}).sort((a, b) => b.count - a.count);
|
||||
decimated = [0];
|
||||
for (let {count, hue} of popularHues) {
|
||||
let luma = lumaByHue[hue];
|
||||
if (luma > 0 && count > 0) {
|
||||
decimated.push((hue << 4) | luma);
|
||||
}
|
||||
if (decimated.length == n) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
while (decimated.length > n) {
|
||||
let {popularity, fitness, output} = dither(decimated);
|
||||
|
||||
|
@ -509,8 +563,9 @@ function decimate(input, palette, n, inputError) {
|
|||
continue;
|
||||
}
|
||||
|
||||
let coolFactor = fitness[i] * popularity[i];
|
||||
//let coolFactor = popularity[i];
|
||||
let coolFactor = (fitness[i] ** 2) * popularity[i];
|
||||
//let coolFactor = (fitness[i] ** 2) * popularity[i];
|
||||
|
||||
if (coolFactor < least) {
|
||||
pick = i;
|
||||
|
@ -534,6 +589,7 @@ function decimate(input, palette, n, inputError) {
|
|||
throw new Error('this should not happen');
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Palette fits
|
||||
return dither(decimated);
|
||||
|
|
Loading…
Reference in a new issue