func NewLgtm(file *multipart.File, header *multipart.FileHeader) (*Lgtm, error) { input, err := gif.DecodeAll(*file) if err != nil { return nil, err } output, err := yosage.Generate(input) if err != nil { return nil, err } var b bytes.Buffer writer := bufio.NewWriter(&b) err = gif.EncodeAll(writer, output) if err != nil { return nil, err } writer.Flush() re := regexp.MustCompile(`\.(gif|GIF)$`) return &Lgtm{ Filename: re.ReplaceAllString(header.Filename, "") + "_lgtm.gif", Data: base64.StdEncoding.EncodeToString(b.Bytes()), }, nil }
func lissajous(out io.Writer) { const ( cycles = 5 // number of complete x oscillator revolutions res = 0.001 // angular resolution size = 100 // image canvas covers [-size..+size] nframes = 64 // number of animation frames delay = 8 // delay between frames in 10ms units ) freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) index := uint8(rand.Int() % len(palette)) // random palette index color if index == 0 { index = 1 // change the index if the color is the same as the background color } for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), index) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } if err := gif.EncodeAll(out, &anim); err != nil { log.Fatal(err) } }
func lissajous(out http.ResponseWriter, r *http.Request) { const ( cycles = 5 res = 0.001 size = 100 nframes = 64 delay = 8 ) freq := rand.Float64() * 3.0 anim := gif.GIF{LoopCount: nframes} phase := 0.0 for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) }
// Writter writes a Gif // @param out a Writter // @param cycles number of complete x oscillator revolutions func Writter(out io.Writer, cycles float64) { const ( res = 0.001 // angular resolution size = 100 // image canvas covers [-size..+size] nframes = 64 // number of animation frames delay = 8 // delay between frames in 10ms units ) freq := rand.Float64() * 12.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, pallete) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) if i%2 == 0 { img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), greenIndex) } else { img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blueIndex) } } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) }
func FuzzAll(data []byte) int { cfg, err := gif.DecodeConfig(bytes.NewReader(data)) if err != nil { return 0 } if cfg.Width*cfg.Height > 1e6 { return 0 } img, err := gif.DecodeAll(bytes.NewReader(data)) if err != nil { return 0 } w := new(bytes.Buffer) err = gif.EncodeAll(w, img) if err != nil { panic(err) } img1, err := gif.DecodeAll(w) if err != nil { panic(err) } if img.LoopCount == 0 && img1.LoopCount == -1 { // https://github.com/golang/go/issues/11287 img1.LoopCount = 0 } // https://github.com/golang/go/issues/11288 img1.Disposal = img.Disposal if !fuzz.DeepEqual(img, img1) { fmt.Printf("gif0: %#v\n", img) fmt.Printf("gif1: %#v\n", img1) panic("gif changed") } return 1 }
func lissajous(out http.ResponseWriter, r *http.Request) { const ( res = 0.001 // angular resolution size = 500 // image canvas covers [-size..+size] nframes = 64 // number of animation frames delay = 8 // delay between frames in 10ms units ) if err := r.ParseForm(); err != nil { os.Exit(1) } for k, v := range r.Form { fmt.Printf("%s:%s\n", k, v) } cyclesInt, _ := strconv.Atoi(r.Form.Get("cycles")) // number of complete x oscillator revolutions cycles := float64(cyclesInt) fmt.Printf("Float is: %f\n", cycles) freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors }
// Process the GIF read from r, applying transform to each frame, and writing // the result to w. func Process(w io.Writer, r io.Reader, transform TransformFunc) error { if transform == nil { _, err := io.Copy(w, r) return err } // Decode the original gif. im, err := gif.DecodeAll(r) if err != nil { return err } // Create a new RGBA image to hold the incremental frames. firstFrame := im.Image[0].Bounds() b := image.Rect(0, 0, firstFrame.Dx(), firstFrame.Dy()) img := image.NewRGBA(b) // Resize each frame. for index, frame := range im.Image { bounds := frame.Bounds() draw.Draw(img, bounds, frame, bounds.Min, draw.Over) im.Image[index] = imageToPaletted(transform(img), frame.Palette) } // Set image.Config to new height and width im.Config.Width = im.Image[0].Bounds().Max.X im.Config.Height = im.Image[0].Bounds().Max.Y return gif.EncodeAll(w, im) }
func lissajous(write http.ResponseWriter, read *http.Request) { const ( res = 0.001 // angular resolution size = 100 // image canvas covers [-size..+size] nframes = 64 // number of animation frames delay = 8 // delay between frames in 10ms units ) cycles, _ := strconv.Atoi(read.URL.Query()["cycles"][0]) freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < float64(cycles)*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(write, &anim) // NOTE: ignoring encoding errors }
func lissajous(out io.Writer, cycles int) { rand.Seed(time.Now().UTC().UnixNano()) const ( res = 0.001 size = 100 nframes = 64 delay = 8 ) freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < float64(cycles)*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), uint8(1+rand.Intn(4-1))) // randomly generated color } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors }
func lissajous(out io.Writer) { const ( cycles = 5 res = 0.001 size = 100 nframes = 64 delay = 8 ) freq := rand.Float64() * 3.0 anim := gif.GIF{LoopCount: nframes} phase := 0.0 for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), greenIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } err := gif.EncodeAll(out, &anim) if err != nil { panic("Gif encoding error") } }
func mainDrawAnimation() error { log.Printf("Drawing animation") iterations := 8 imageWidth := 512.0 g := gif.GIF{ Image: make([]*image.Paletted, iterations), Delay: make([]int, iterations), LoopCount: 0, } for i := 0; i < iterations; i++ { log.Printf(" Drawing frame %d", i) n := 1 << uint(i+1) h := CreateHilbertImage(n, imageWidth/float64(n)) h.DrawText = false img, err := h.Draw() if err != nil { return err } g.Image[i] = convertToPaletted(img) // draw2d doesn't support paletted images, so we convert g.Delay[i] = 200 // 200 x 100th of a second = 2 second } f, err := os.Create("hilbert_animation.gif") if err != nil { return err } return gif.EncodeAll(f, &g) }
func main() { var images []*image.Paletted var delays []int f, _ := os.Create("foo.gif") rect := image.Rect(0, 0, 28+24*4, 20+18*10) // not a loop anymore m := image.NewPaletted(rect, pal) black := pal.Convert(color.RGBA{0, 0, 0, 255}) draw.Draw(m, rect, &image.Uniform{black}, image.ZP, draw.Src) for i := 0; i < 10; i++ { for j := 0; j < 4; j++ { x := 10 + j*24 y := 10 + i*18 if i%2 == 1 { x += 12 } drawHex(m, x, y, 20) } } images = append(images, m) delays = append(delays, 10) // end of not a loop anymore anim := gif.GIF{Image: images, Delay: delays, LoopCount: 1000} gif.EncodeAll(f, &anim) }
func process_file(filename string) error { f, err := os.Open(filename) if err != nil { return err } defer f.Close() reader := bufio.NewReader(f) g, err := gif.DecodeAll(reader) if err != nil { return err } err = debarf_image(g) of, err := os.Create("out.gif") if err != nil { return err } defer of.Close() writer := bufio.NewWriter(of) err = gif.EncodeAll(writer, g) if err != nil { return err } return err }
func lissajous(out io.Writer, cycles int) { if cycles == 0 { cycles = 5 } const ( res = 0.001 size = 100 nframes = 64 delay = 8 ) freq := rand.Float64() * 3.0 anim := gif.GIF{LoopCount: nframes} phase := 0.0 for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) color := rand.Intn(216) for t := 0.0; t < float64(cycles)*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), uint8(color)) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) }
func lissajous(out io.Writer, config map[string]int) { cycles := 5 // number of complete x oscillator revolutions res := 0.001 // angular resolution size := 100 // image canvas covers [-size..+size] nframes := 63 // number of animation frames delay := 8 // delay between frames in 10ms units if v, ok := config["cycles"]; ok { cycles = v } if v, ok := config["size"]; ok { size = v } freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < float64(cycles)*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*float64(size)+0.5), size+int(y*float64(size)+0.5), greenIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors }
func mainDrawAnimation(filename string, newAlgo func(n int) hilbert.SpaceFilling, min, max int) error { log.Printf("Drawing animation %q", filename) iterations := max - min imageWidth, imageHeight := 512.0, 512.0 g := gif.GIF{ Image: make([]*image.Paletted, iterations), Delay: make([]int, iterations), LoopCount: 0, } for i := 0; i < iterations; i++ { log.Printf(" Drawing frame %d", i) s := newAlgo(min + i) width, height := s.GetDimensions() h := createSpaceFillingImage(s, imageWidth/float64(width), imageHeight/float64(height)) h.DrawText = false img, err := h.Draw() if err != nil { return err } g.Image[i] = convertToPaletted(img) // draw2d doesn't support paletted images, so we convert g.Delay[i] = 200 // 200 x 100th of a second = 2 second } f, err := os.Create(filename) if err != nil { return err } return gif.EncodeAll(f, &g) }
func lissajous(out io.Writer) { const ( cycles = 5 res = 0.001 size = 100 nframes = 64 delay = 8 ) freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), greenIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors }
func lissajous(out io.Writer, user_vals map[string]Float) { const ( res = 0.001 // angular resolution ) vals := combineUserAndDefaultVals(user_vals) cycles := vals["cycles"] size := vals["size"] nframes := vals["nframes"] delay := vals["delay"] fmt.Printf("%d %d %d %d\n", cycles, size, nframes, delay) freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), linesIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors }
func lissajous(out io.Writer) { const ( cycles = 5 // number of complete x oscillator revolutions res = 0.001 // angular resolution size = 100 // image canvas covers [-size..+size] nframes = 64 // number of animation frames delay = 8 // delay between frames in 10ms units ) freq := rand.Float64() * 3.0 // relative frequency of y oscillator // gif.GIF is a struct type. Somehow this allows the struct to be initialized with nframes, // the rest are 0 due to some defaulting. anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) // BobK: I have no idea what int(x*size+0.5) is doing img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors }
func generateGIF(filenames []string, outPath string) error { fmt.Printf("Generating GIF in %s\n", outPath) uiprogress.Start() bar := uiprogress.AddBar(len(filenames)).AppendCompleted() anim := gif.GIF{LoopCount: len(filenames)} for _, filename := range filenames { reader, err := os.Open(filename) if err != nil { return err } defer reader.Close() img, _, err := image.Decode(reader) if err != nil { return err } bounds := img.Bounds() drawer := draw.FloydSteinberg palettedImg := image.NewPaletted(bounds, palette.Plan9) drawer.Draw(palettedImg, bounds, img, image.ZP) anim.Image = append(anim.Image, palettedImg) anim.Delay = append(anim.Delay, *delay) bar.Incr() } file, err := os.Create(outPath) defer file.Close() if err != nil { return err } encodeErr := gif.EncodeAll(file, &anim) if encodeErr != nil { return encodeErr } return nil }
func lissajous(out io.Writer) { const ( cycles = 5 res = 0.001 size = 100 nframes = 128 delay = 24 ) genGradientPalette(nframes) freq := rand.Float64() * 3.0 anim := gif.GIF{LoopCount: nframes} phase := 0.0 for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), uint8(i+1)) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) }
func (bam *BAM) MakeGif(outputPath string, name string) error { for idx, seq := range bam.Sequences { if seq.Start >= 0 && seq.Count > 0 { pathname := filepath.Join(outputPath, fmt.Sprintf("%s_%03d.gif", name, idx)) g := gif.GIF{} g.Image = make([]*image.Paletted, seq.Count) g.Delay = make([]int, seq.Count) g.LoopCount = 0 for iIdx := seq.Start; iIdx < seq.Start+seq.Count; iIdx++ { imgIdx := int(bam.SequenceToImage[iIdx]) g.Image[iIdx-seq.Start] = &bam.Image[imgIdx] g.Delay[iIdx-seq.Start] = 10 } outFile, err := os.Create(pathname) if err != nil { return fmt.Errorf("Unable to create file %s: %v", pathname, err) } gif.EncodeAll(outFile, &g) outFile.Close() } } return nil }
func (s *Screening) createGIF(force bool) error { fn := s.GIFPath() if !force { if _, err := os.Stat(fn); err == nil { return nil } } outGIF := &gif.GIF{} for i := uint(0); i < s.Steps; i++ { f, err := os.Open(s.ScreenshotPath(i)) if err != nil { return err } defer f.Close() img, err := png.Decode(f) if err != nil { return err } paletted := image2paletted(720, img) outGIF.Image = append(outGIF.Image, paletted) outGIF.Delay = append(outGIF.Delay, 100) } f, err := os.Create(fn) if err != nil { return err } defer f.Close() return gif.EncodeAll(f, outGIF) }
func lissajous(out io.Writer, c float64, col color.RGBA) { var palette = []color.Color{color.White, col} const ( res = 0.01 // angular resolution size = 100 // image canvas covers [-size ... +size] nframes = 64 // number of animation frames delay = 8 // delay between frames in 10ms units ) freq := rand.Float64() * 3 anim := gif.GIF{LoopCount: nframes} phase := 0.0 cycles := float64(c) for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) }
// Handle implements Handler. func (hdr *Handler) Handle(im *imageserver.Image, params imageserver.Params) (*imageserver.Image, error) { if im.Format != "gif" { return nil, &imageserver.ImageError{Message: fmt.Sprintf("image format is not gif: %s", im.Format)} } if !hdr.Processor.Change(params) { return im, nil } g, err := gif.DecodeAll(bytes.NewReader(im.Data)) if err != nil { return nil, &imageserver.ImageError{Message: err.Error()} } g, err = hdr.Processor.Process(g, params) if err != nil { return nil, err } buf := new(bytes.Buffer) err = gif.EncodeAll(buf, g) if err != nil { return nil, &imageserver.ImageError{Message: err.Error()} } im = &imageserver.Image{ Format: "gif", Data: buf.Bytes(), } return im, nil }
func lissajous(out io.Writer, cycles int) { palette := []color.Color{color.White, color.Black} const ( res = 0.001 size = 100 nframes = 64 delay = 8 whiteIndex = 0 blackIndex = 1 ) freq := rand.Float64() * 3.0 // relative Frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) }
func lissajous(out io.Writer) { palette := []color.Color{color.Black} for i := 0; i < nFrames; i++ { red := (uint8)((i * 255) / nFrames) green := (uint8)(((i + nFrames/2) * 255) / nFrames) blue := (uint8)(((nFrames/2 - i) * 255) / nFrames) palette = append(palette, color.RGBA{red, green, blue, 0xff}) } freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nFrames} phase := 0.0 for i := 0; i < nFrames; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) xcoord := size + int(x*(float64)(size)+0.5) ycoord := size + int(y*(float64)(size)+0.5) img.SetColorIndex(xcoord, ycoord, (uint8)(i+1)) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) }
func writeGIF(filename string, imgs []image.Image) error { f, err := os.Create(filename) if err != nil { return err } defer f.Close() g := gif.GIF{ Image: make([]*image.Paletted, len(imgs)), Delay: make([]int, len(imgs)), } b := make([]byte, 0, 1024) for i, img := range imgs { buf := bytes.NewBuffer(b) if err = gif.Encode(buf, img, &gif.Options{NumColors: 256}); err != nil { return err } gimg, err := gif.DecodeAll(buf) if err != nil { return err } g.Delay[i] = 0 g.Image[i] = gimg.Image[0] } return gif.EncodeAll(f, &g) }
func lissajous(out io.Writer) { const ( cycles = 5 // number of complete x oscillator revolutions res = 0.001 // angular resolution size = 100 // image canvas covers [-size..+size] nframes = 64 // number of animation frames delay = 8 // delay between frames in 10ms units ) freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), uint8(i)%3+1) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors }
// handler that displays lissajous figures in the browser func lissajous(out io.Writer) { hit() // Increment 'total hits' metric l_start := time.Now() const ( cycles = 5 // number of complete x oscillator revolutions res = 0.001 // angular resolution size = 400 // image canvas covers [-size..+size] nframes = 64 // number of animation frames delay = 8 // delay between frames in 10ms units ) freq := rand.Float64() * 3.0 // relative frequency of y oscillator anim := gif.GIF{LoopCount: nframes} phase := 0.0 // phase difference for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors l_secs := time.Since(l_start).Seconds() stats.Timing("lissajous.load.time", int64(l_secs)) // Metric to record time to load a figure stats.Incr("lissajous.pageview.count", 1) // Metric to record hits per cycle for this handler }