diff --git a/dither4.js b/dither4.js index 9d40627..00978fd 100644 --- a/dither4.js +++ b/dither4.js @@ -12,6 +12,27 @@ class RGB { return new RGB(r,g,b); } + cap() { + if (this.r < 0) { + this.r = 0; + } + if (this.g < 0) { + this.g = 0; + } + if (this.b < 0) { + this.b = 0; + } + if (this.r > 255) { + this.r = 255; + } + if (this.g > 255) { + this.g = 255; + } + if (this.b > 255) { + this.b = 255; + } + } + add(other) { return new RGB( this.r + other.r, @@ -335,14 +356,15 @@ function decimate(input, palette, n) { // Try dithering with this palette. for (let x = 0; x < line.length; x++) { let rgb = line[x]; - rgb = rgb.difference(error.right); + rgb = rgb.add(error.right); + rgb.cap(); // find the closest possible color let shortest = Infinity; let pick = -1; for (let i = 0; i < palette.length; i++) { - let diff = palette[i].difference(rgb); + let diff = rgb.difference(palette[i]); let dist = diff.magnitude(); if (dist < shortest) { nextError = diff; @@ -361,19 +383,23 @@ function decimate(input, palette, n) { error.right.b = nextError.b; */ + /* error.right.r = nextError.r / 2; error.right.g = nextError.g / 2; error.right.b = nextError.b / 2; - if (x == 0) { - error.red[x - 1] += nextError.r / 8; - error.green[x - 1] += nextError.g / 8; - error.blue[x - 1] += nextError.b / 8; - } else { - error.red[x] += nextError.r / 8; - error.green[x] += nextError.g / 8; - error.blue[x] += nextError.b / 8; - } + error.red[x + 1] += nextError.r / 2; + error.green[x + 1] += nextError.g / 2; + error.blue[x + 1] += nextError.b / 2; + */ + + error.right.r = nextError.r / 2; + error.right.g = nextError.g / 2; + error.right.b = nextError.b / 2; + + error.red[x - 1] += nextError.r / 8; + error.green[x - 1] += nextError.g / 8; + error.blue[x - 1] += nextError.b / 8; error.red[x] += nextError.r / 4; error.green[x] += nextError.g / 4; @@ -383,7 +409,7 @@ function decimate(input, palette, n) { error.green[x + 1] += nextError.g / 8; error.blue[x + 1] += nextError.b / 8; - fitness[x] = 1 / nextError.magnitude(); + fitness[x] = 1 - (nextError.magnitude() / 442); } return { output, @@ -407,13 +433,13 @@ function decimate(input, palette, n) { continue; // keep black always } if (decimated[i].r == 255 && decimated[i].g == 255 && decimated[i].b == 255) { - //continue; // keep white always + continue; // keep white always } let coolFactor = popularity[i]; /* for (let x = 0; x < line.length; x++) { if (output[x] == i) { - coolFactor *= fitness[i]; + coolFactor *= fitness[x]; } } */ @@ -475,13 +501,10 @@ function convert(source, sink) { (line[x * 4 + 2] + line[x * 4 + 6]) / 2 ); if (nextError) { - rgb.r -= nextError.red[i]; - rgb.g -= nextError.green[i]; - rgb.b -= nextError.blue[i]; - } else { - if (y > 0) { - debugger; - } + rgb.r += nextError.red[i]; + rgb.g += nextError.green[i]; + rgb.b += nextError.blue[i]; + rgb.cap(); } input.push(rgb); }