package main import ( "fmt" "image" "image/color" "image/gif" "log" "sort" "git.red-green.com/david/point2d" ) type HitList []point2d.Point func (h HitList) Len() int { return len(h) } func (h HitList) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h HitList) Less(i, j int) bool { return h[i].LessThan(&h[j]) } func Scan(filename string) (hits []HitList, err error) { var ( gif *gif.GIF size image.Point pix color.Color r uint32 g uint32 b uint32 hitframe HitList ) gif, err = DecodeGif(filename) if err != nil { return nil, fmt.Errorf("DecodeGif(\"%s\") > %v", filename, err) } for _, frame := range gif.Image { size = frame.Bounds().Size() hitframe = HitList{} for y := range make([]byte, size.Y) { for x := range make([]byte, size.X) { pix = frame.At(x, y) r, g, b, _ = pix.RGBA() r /= 255 g /= 255 b /= 255 // Now to determine if this pixel is considerable as rain if (r <= 47 && g >= 90 && b <= 51) || (r >= 240 && g >= 240 && b <= 10) || (r >= 240 && g <= 10 && b <= 10) { //fmt.Printf("{(%d, %d) [%d, %d, %d, %s]}\r\n", x, y, r, g, b, rgbToHex(r, g, b)) frame.Set(x, y, color.RGBA{R: 255, G: 0, B: 0, A: 255}) hitframe = append(hitframe, *point2d.AsPoint(x, y)) } } } hits = append(hits, hitframe) } err = EncodeGif(filename+".out", gif) if err != nil { return nil, fmt.Errorf("EncodeGif(\"%s.out\", gif) > %v", filename, err) } return hits, nil } func main() { var ( err error hits []HitList diff point2d.Point ) /* err = GrabPascoGif() if err != nil { log.Panic("GrabPascoGif() >", err) } */ hits, err = Scan("pasco.gif") if err != nil { log.Panic(err) } for _, frame := range hits { sort.Sort(&frame) } for _, pos := range hits[0] { if diff.IsZero() { diff = pos } else { dist := diff.DistanceTo(&pos) if dist > 1 { fmt.Printf("0] (%s) diff=(%s) dist=%d\r\n", pos.String(), diff.String(), dist) } if dist > 1 { diff = pos } } } }