Compare commits

..

No commits in common. "cbe14d53cda6524c1d33b2e22a4539db80d452e7" and "b8b7ff71671e0412004f2398851f5a861b0f7d8d" have entirely different histories.

2 changed files with 16 additions and 88 deletions

View File

@ -51,12 +51,6 @@ func main() {
new = apply(i, bayerDithering(1, true)) new = apply(i, bayerDithering(1, true))
case "simpleerror": case "simpleerror":
new = apply(i, simpleErrorDiffusion()) new = apply(i, simpleErrorDiffusion())
case "floydsteinberg":
new = apply(i, floydSteinberg())
case "jjn":
new = apply(i, jarvisJudiceNinke())
case "atkinson":
new = apply(i, atkinson())
default: default:
fmt.Printf("unknown ditherer option: %s\n", ditherer) fmt.Printf("unknown ditherer option: %s\n", ditherer)
os.Exit(2) os.Exit(2)

View File

@ -122,96 +122,30 @@ func bayerDithering(level int, invert bool) quantizerFunction {
} }
} }
type diffusion struct { func applyError(diffusionMatrix map[coord]float64, divisor float64, quantError float64, currentPixel coord, errMap map[coord]float64) {
matrix map[coord]float64 for c, i := range diffusionMatrix {
divisor float64
}
func applyError(diffusion diffusion, quantError float64, currentPixel coord, errMap map[coord]float64) {
for c, i := range diffusion.matrix {
target := coord{x: currentPixel.x + c.x, y: currentPixel.y + c.y} target := coord{x: currentPixel.x + c.x, y: currentPixel.y + c.y}
errMap[target] = errMap[target] + (quantError * (i / diffusion.divisor)) errMap[target] = errMap[target] + (quantError * (i / divisor))
}
}
func diffuser(errMap map[coord]float64, d diffusion) quantizerFunction {
return func(x int, y int, c color.Color) color.Color {
p := coord{x: x, y: y}
l := luminence(c) + errMap[p]
delete(errMap, p) // don't let the error map grow too big
if l > 0.5 {
applyError(d, l-1.0, p, errMap)
return color.White
}
applyError(d, l, p, errMap)
return color.Black
} }
} }
func simpleErrorDiffusion() quantizerFunction { func simpleErrorDiffusion() quantizerFunction {
errMap := make(map[coord]float64) errMap := make(map[coord]float64)
d := diffusion{ diffusionMatrix := map[coord]float64{
divisor: 2.0, {x: 1, y: 0}: 1.0,
matrix: map[coord]float64{ {x: 0, y: 1}: 1.0,
{x: 1, y: 0}: 1.0,
{x: 0, y: 1}: 1.0,
},
} }
return diffuser(errMap, d) return func(x int, y int, c color.Color) color.Color {
} p := coord{x: x, y: y}
l := luminence(c) + errMap[p]
func floydSteinberg() quantizerFunction { delete(errMap, p) // don't let the error map grow too big
errMap := make(map[coord]float64) if l > 0.5 {
d := diffusion{ applyError(diffusionMatrix, 2.0, l-1.0, p, errMap)
divisor: 16.0, return color.White
matrix: map[coord]float64{ }
{x: 1, y: 0}: 7.0, applyError(diffusionMatrix, 2.0, l, p, errMap)
{x: -1, y: 1}: 3.0, return color.Black
{x: 0, y: 1}: 5.0,
{x: 1, y: 1}: 1.0,
},
} }
return diffuser(errMap, d)
}
func jarvisJudiceNinke() quantizerFunction {
errMap := make(map[coord]float64)
d := diffusion{
divisor: 48.0,
matrix: map[coord]float64{
{x: 1, y: 0}: 7.0,
{x: 2, y: 0}: 5.0,
{x: -2, y: 1}: 3.0,
{x: -1, y: 1}: 5.0,
{x: 0, y: 1}: 7.0,
{x: 1, y: 1}: 5.0,
{x: 2, y: 1}: 3.0,
{x: -2, y: 2}: 1.0,
{x: -1, y: 2}: 3.0,
{x: 0, y: 2}: 5.0,
{x: 1, y: 2}: 3.0,
{x: 2, y: 2}: 1.0,
},
}
return diffuser(errMap, d)
}
func atkinson() quantizerFunction {
errMap := make(map[coord]float64)
d := diffusion{
divisor: 8.0,
matrix: map[coord]float64{
{x: 1, y: 0}: 1.0,
{x: 2, y: 0}: 1.0,
{x: -1, y: 1}: 1.0,
{x: 0, y: 1}: 1.0,
{x: 1, y: 1}: 1.0,
{x: 0, y: 2}: 1.0,
},
}
return diffuser(errMap, d)
} }
// That is, "relative luminance": https://en.wikipedia.org/wiki/Relative_luminance. // That is, "relative luminance": https://en.wikipedia.org/wiki/Relative_luminance.