wip
This commit is contained in:
parent
f5c8d219e8
commit
1d3712be5c
1 changed files with 14 additions and 29 deletions
|
@ -134,13 +134,23 @@ class RGB {
|
|||
this.b * this.b;
|
||||
}
|
||||
|
||||
sum() {
|
||||
return this.r + this.g + this.b;
|
||||
}
|
||||
|
||||
lumaScale() {
|
||||
return new RGB(
|
||||
this.r * 0.299,
|
||||
this.g * 0.586,
|
||||
this.b * 0.114
|
||||
);
|
||||
}
|
||||
|
||||
luma() {
|
||||
return this.r * 0.299 + this.g * 0.587 + this.b * 0.114;
|
||||
return this.lumaScale().sum();
|
||||
}
|
||||
}
|
||||
|
||||
const maxDist = (new RGB(255, 255, 255)).magnitude();
|
||||
|
||||
// snarfed from https://lospec.com/palette-list/atari-8-bit-family-gtia
|
||||
// which was calculated with Retrospecs App's Atari 800 emulator
|
||||
let atariRGB = [
|
||||
|
@ -414,19 +424,6 @@ let atariRGB = [
|
|||
* @returns {{output: number[], palette: number[], error: RGB[]}}
|
||||
*/
|
||||
function decimate(input, palette, n) {
|
||||
// to brute-force, the possible palettes are:
|
||||
// 255 * 254 * 253 = 16,386,810
|
||||
//
|
||||
// we could brute force it but that's a lot :D
|
||||
// but can do some bisection :D
|
||||
//
|
||||
// need a fitness metric.
|
||||
// each pixel in the dithered line gives a distance
|
||||
// sum/average them? median? maximum?
|
||||
// summing evens out the ups/downs from dithering
|
||||
// but doesn't distinguish between two close and two distant options
|
||||
// consider median, 90th-percentile, and max of abs(distance)
|
||||
// consider doing the distance for each channel?
|
||||
|
||||
let width = input.length;
|
||||
|
||||
|
@ -440,7 +437,6 @@ function decimate(input, palette, n) {
|
|||
|
||||
// Apply dithering with given palette and collect color usage stats
|
||||
let dither = (palette) => {
|
||||
let fitness = zeroes(width);
|
||||
let error = {
|
||||
cur: [],
|
||||
next: [],
|
||||
|
@ -467,7 +463,7 @@ function decimate(input, palette, n) {
|
|||
|
||||
for (let i = 0; i < palette.length; i++) {
|
||||
let diff = rgb.difference(atariRGB[palette[i]]);
|
||||
let dist = diff.magnitude2();
|
||||
let dist = diff.magnitude();
|
||||
if (dist < shortest) {
|
||||
nextError = diff;
|
||||
shortest = dist;
|
||||
|
@ -484,21 +480,10 @@ function decimate(input, palette, n) {
|
|||
error.next[x - 1]?.inc(share(3));
|
||||
error.next[x ]?.inc(share(5));
|
||||
error.next[x + 1]?.inc(share(1));
|
||||
|
||||
let mag = nextError.magnitude();
|
||||
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));
|
||||
|
||||
let mag2 = nextError.magnitude2();
|
||||
distance2 += mag2;
|
||||
}
|
||||
return {
|
||||
output,
|
||||
palette,
|
||||
fitness,
|
||||
distance2,
|
||||
popularity,
|
||||
error: error.next
|
||||
|
|
Loading…
Reference in a new issue