main.go - randomcrap - random crap programs of varying quality
(HTM) git clone git://git.codemadness.org/randomcrap
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
main.go (1577B)
---
1 /* image to black and white pallet using Floyd-Steinberg dithering */
2 package main
3
4 import (
5 "image"
6 "image/color"
7 "image/jpeg"
8 "image/png"
9 "os"
10 )
11
12 func round(f float64) float64 {
13 f += 0.5
14 f *= 10
15 return float64(int64(f) / 10)
16 }
17
18 func main() {
19 img, err := jpeg.Decode(os.Stdin)
20 if err != nil {
21 panic(err)
22 }
23
24 b := img.Bounds()
25 w := b.Max.X
26 h := b.Max.Y
27
28 pixels := make([][]float64, w)
29 for x := 0; x < w; x++ {
30 pixels[x] = make([]float64, h)
31 }
32
33 for y := 0; y < h; y++ {
34 for x := 0; x < w; x++ {
35 c := img.At(x, y)
36 r, g, b, _ := c.RGBA()
37 pixels[x][y] = 1.0 / (float64(0xffff) / (float64(r+g+b) / 3.0))
38 }
39 }
40
41 for y := 0; y < h; y++ {
42 for x := 0; x < w; x++ {
43 o := pixels[x][y]
44 n := round(o) // black and white
45 pixels[x][y] = n
46 quant_error := o - n
47
48 if x+1 < w {
49 pixels[x+1][y] = pixels[x+1][y] + quant_error*7.0/16.0
50 }
51 if x > 0 && y+1 < h {
52 pixels[x-1][y+1] = pixels[x-1][y+1] + quant_error*3.0/16.0
53 }
54 if y+1 < h {
55 pixels[x][y+1] = pixels[x][y+1] + quant_error*5.0/16.0
56 }
57 if x+1 < w && y+1 < h {
58 pixels[x+1][y+1] = pixels[x+1][y+1] + quant_error*1.0/16.0
59 }
60 }
61 }
62
63 // output
64 out, err := os.OpenFile("output.png", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
65 if err != nil {
66 panic(err)
67 }
68 defer out.Close()
69
70 newimg := image.NewNRGBA(image.Rect(0, 0, w, h))
71 for y := 0; y < h; y++ {
72 for x := 0; x < w; x++ {
73 v8 := uint8(round(pixels[x][y] * 255.0))
74 newimg.Set(x, y, color.NRGBA{R: v8, G: v8, B: v8, A: 255})
75 }
76 }
77 err = png.Encode(out, newimg)
78 if err != nil {
79 panic(err)
80 }
81 }