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 }