From e460fcefb0543315eb738ed7e8c93b9b9b779c02 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sun, 4 Dec 2022 15:03:36 -0800 Subject: [PATCH] wip dither tweaks --- dither-image.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/dither-image.js b/dither-image.js index 717f1ef..141fa12 100644 --- a/dither-image.js +++ b/dither-image.js @@ -78,14 +78,18 @@ class RGB { return this; } - add(other) { + static add(a, b) { return new RGB( - this.r + other.r, - this.g + other.g, - this.b + other.b + a.r + b.r, + a.g + b.g, + a.b + b.b ); } + add(other) { + return RGB.add(this, other); + } + difference(other) { return new RGB( this.r - other.r, @@ -407,10 +411,11 @@ function decimate(input, palette, n, inputError) { let dither = (palette) => { let fitness = new Float64Array(width); let error = { - right: new RGB(0, 0, 0), + cur: [], next: [], }; for (let i = 0; i < width; i++) { + error.cur[i] = new RGB(0, 0, 0); error.next[i] = new RGB(0, 0, 0); } @@ -421,8 +426,7 @@ function decimate(input, palette, n, inputError) { // Try dithering with this palette. for (let x = 0; x < width; x++) { - let rgb = input[x]; - rgb = rgb.add(error.right); + let rgb = RGB.add(input[x], error.cur[x]); if (inputError) { rgb.inc(inputError[x]); } @@ -445,18 +449,14 @@ function decimate(input, palette, n, inputError) { output[x] = pick; popularity[pick]++; - if (x == width - 1) { - let half = nextError.divide(4); - error.next[x - 1].inc(half); - error.next[x].inc(half); - // drop half the error on the floor at the edge ;_; - } else { - let quarter = nextError.divide(4); - error.right = quarter; - error.next[x - 1]?.inc(quarter); // @fixme should we change the amount? - error.next[x].inc(quarter); - error.next[x + 1].inc(quarter); - } + let shares = 8; + let single = nextError.divide(shares); + let double = nextError.divide(shares / 2); + error.cur[x + 1]?.inc(double); + error.cur[x + 2]?.inc(single); + error.next[x - 1]?.inc(double); + error.next[x]?.inc(double); + error.next[x + 1]?.inc(single); // 442 is the 3d distance across the rgb cube //fitness[x] = 442 - (nextError.magnitude());