func TestEncodeAllFramesOutOfBounds(t *testing.T) { images := []*image.Paletted{ image.NewPaletted(image.Rect(0, 0, 5, 5), palette.Plan9), image.NewPaletted(image.Rect(2, 2, 8, 8), palette.Plan9), image.NewPaletted(image.Rect(3, 3, 4, 4), palette.Plan9), } for _, upperBound := range []int{6, 10} { g := &GIF{ Image: images, Delay: make([]int, len(images)), Disposal: make([]byte, len(images)), Config: image.Config{ Width: upperBound, Height: upperBound, }, } err := EncodeAll(ioutil.Discard, g) if upperBound >= 8 { if err != nil { t.Errorf("upperBound=%d: %v", upperBound, err) } } else { if err == nil { t.Errorf("upperBound=%d: got nil error, want non-nil", upperBound) } } } }
func TestEncodePalettes(t *testing.T) { const w, h = 5, 5 pals := []color.Palette{{ color.RGBA{0x00, 0x00, 0x00, 0xff}, color.RGBA{0x01, 0x00, 0x00, 0xff}, color.RGBA{0x02, 0x00, 0x00, 0xff}, }, { color.RGBA{0x00, 0x00, 0x00, 0xff}, color.RGBA{0x00, 0x01, 0x00, 0xff}, }, { color.RGBA{0x00, 0x00, 0x03, 0xff}, color.RGBA{0x00, 0x00, 0x02, 0xff}, color.RGBA{0x00, 0x00, 0x01, 0xff}, color.RGBA{0x00, 0x00, 0x00, 0xff}, }, { color.RGBA{0x10, 0x07, 0xf0, 0xff}, color.RGBA{0x20, 0x07, 0xf0, 0xff}, color.RGBA{0x30, 0x07, 0xf0, 0xff}, color.RGBA{0x40, 0x07, 0xf0, 0xff}, color.RGBA{0x50, 0x07, 0xf0, 0xff}, }} g0 := &GIF{ Image: []*image.Paletted{ image.NewPaletted(image.Rect(0, 0, w, h), pals[0]), image.NewPaletted(image.Rect(0, 0, w, h), pals[1]), image.NewPaletted(image.Rect(0, 0, w, h), pals[2]), image.NewPaletted(image.Rect(0, 0, w, h), pals[3]), }, Delay: make([]int, len(pals)), Disposal: make([]byte, len(pals)), Config: image.Config{ ColorModel: pals[2], Width: w, Height: h, }, } var buf bytes.Buffer if err := EncodeAll(&buf, g0); err != nil { t.Fatalf("EncodeAll: %v", err) } g1, err := DecodeAll(&buf) if err != nil { t.Fatalf("DecodeAll: %v", err) } if len(g0.Image) != len(g1.Image) { t.Fatalf("image lengths differ: %d and %d", len(g0.Image), len(g1.Image)) } for i, m := range g1.Image { if got, want := m.Palette, pals[i]; !palettesEqual(got, want) { t.Errorf("frame %d:\ngot %v\nwant %v", i, got, want) } } }
func (b *ProgressBar) MakeGraphics() { p := color.Palette{b.Widget.Background, b.Widget.Foreground} b.graphics = make([]*image.Paletted, 1) b.graphics[0] = image.NewPaletted(image.Rectangle{image.ZP, b.Bounds().Size()}, p) r := b.graphics[0].Bounds() border := image.Rectangle{r.Min.Add(image.Point{hIndent, vIndent}), r.Max.Sub(image.Point{hIndent, vIndent})} basic2d.Box(b.graphics[0], border, borderWidth, b.Widget.Foreground) if (b.canvas == nil) || (b.Bounds().Size() != b.canvas.Bounds().Size()) { b.canvas = image.NewPaletted(image.Rectangle{image.ZP, b.Bounds().Size()}, p) } b.Dirty = false }
// DrawImage draws a new image beased on matrix and config ration func (w Walker) CreateAnimationImage(file *os.File) { var palette color.Palette = color.Palette{} palette = append(palette, color.White) palette = append(palette, color.Black) palette = append(palette, color.RGBA{133, 133, 133, 150}) palette = append(palette, color.RGBA{255, 0, 0, 150}) out := &gif.GIF{} ratio := int(w.m.I.GetRatio()) maze := w.m.DrawImage() if len(w.r.t) <= 1000 { for _, t := range w.r.t { rect := image.Rect(t.X*ratio, t.Y*ratio, t.X*ratio+int(w.m.I.GetRatio()), t.Y*ratio+int(w.m.I.GetRatio())) switch true { case OK == (OK & t.T): draw.Draw(maze, rect, &image.Uniform{color.RGBA{255, 0, 0, 150}}, image.ZP, draw.Src) default: draw.Draw(maze, rect, &image.Uniform{color.RGBA{133, 133, 133, 150}}, image.ZP, draw.Src) } pm := image.NewPaletted(maze.Bounds(), palette) draw.FloydSteinberg.Draw(pm, maze.Bounds(), maze, image.ZP) out.Image = append(out.Image, pm) out.Delay = append(out.Delay, 0) } } else { for i := 0; i < len(w.r.t); i++ { rect := image.Rect(w.r.t[i].X*ratio, w.r.t[i].Y*ratio, w.r.t[i].X*ratio+int(w.m.I.GetRatio()), w.r.t[i].Y*ratio+int(w.m.I.GetRatio())) switch true { case OK == (OK & w.r.t[i].T): draw.Draw(maze, rect, &image.Uniform{color.RGBA{255, 0, 0, 150}}, image.ZP, draw.Src) default: draw.Draw(maze, rect, &image.Uniform{color.RGBA{133, 133, 133, 150}}, image.ZP, draw.Src) } if i%100 == 0 { pm := image.NewPaletted(maze.Bounds(), palette) draw.FloydSteinberg.Draw(pm, maze.Bounds(), maze, image.ZP) out.Image = append(out.Image, pm) out.Delay = append(out.Delay, 0) } } } gif.EncodeAll(file, out) }
func (video *GIFRecorder) Run() { for { select { case colors := <-video.input: if video.gif == nil { continue } frame := image.NewPaletted(image.Rect(0, 0, 256, 240), video.palette) x, y := 0, 0 for _, c := range colors { frame.Set(x, y, video.palette[c]) switch x { case 255: x = 0 y++ default: x++ } } video.gif.Image = append(video.gif.Image, frame) video.gif.Delay = append(video.gif.Delay, 3) case <-video.stop: video.stop <- 1 break } } }
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 (video *JPEGRecorder) Run() { video.frame = image.NewPaletted(image.Rect(0, 0, 256, 240), video.palette) for { select { case colors := <-video.input: if video.frame == nil { continue } x, y := 0, 0 for _, c := range colors { video.frame.Set(x, y, video.palette[c]) switch x { case 255: x = 0 y++ default: x++ } } case <-video.stop: video.stop <- 1 break } } }
// decodePaletted reads an 8 bit-per-pixel BMP image from r. // If topDown is false, the image rows will be read bottom-up. func decodePaletted(r io.Reader, c image.Config, topDown bool) (image.Image, error) { paletted := image.NewPaletted(image.Rect(0, 0, c.Width, c.Height), c.ColorModel.(color.Palette)) if c.Width == 0 || c.Height == 0 { return paletted, nil } var tmp [4]byte y0, y1, yDelta := c.Height-1, -1, -1 if topDown { y0, y1, yDelta = 0, c.Height, +1 } for y := y0; y != y1; y += yDelta { p := paletted.Pix[y*paletted.Stride : y*paletted.Stride+c.Width] if _, err := io.ReadFull(r, p); err != nil { return nil, err } // Each row is 4-byte aligned. if c.Width%4 != 0 { _, err := io.ReadFull(r, tmp[:4-c.Width%4]) if err != nil { return nil, err } } } return paletted, nil }
// NewImage returns a new captcha image of the given width and height with the // given digits, where each digit must be in range 0-9. func NewImage(digits []byte, width, height int) *Image { m := new(Image) m.Paletted = image.NewPaletted(image.Rect(0, 0, width, height), randomPalette()) m.calculateSizes(width, height, len(digits)) // Randomly position captcha inside the image. maxx := width - (m.numWidth+m.dotSize)*len(digits) - m.dotSize maxy := height - m.numHeight - m.dotSize*2 var border int if width > height { border = height / 5 } else { border = width / 5 } x := randInt(border, maxx-border) y := randInt(border, maxy-border) // Draw digits. for _, n := range digits { m.drawDigit(font[n], x, y) x += m.numWidth + m.dotSize } // Draw strike-through line. m.strikeThrough() // Apply wave distortion. m.distort(randFloat(5, 10), randFloat(100, 200)) // Fill image with random circles. m.fillWithCircles(circleCount, m.dotSize) return m }
func NewImageOfTypeRect(src image.Image, bounds image.Rectangle) image.Image { switch i := src.(type) { case *image.Alpha: return image.NewAlpha(bounds) case *image.Alpha16: return image.NewAlpha16(bounds) case *image.Gray: return image.NewGray(bounds) case *image.Gray16: return image.NewGray16(bounds) case *image.NRGBA: return image.NewNRGBA(bounds) case *image.NRGBA64: return image.NewNRGBA64(bounds) case *image.Paletted: return image.NewPaletted(bounds, i.Palette) case *image.RGBA: return image.NewRGBA(bounds) case *image.RGBA64: return image.NewRGBA64(bounds) case *image.YCbCr: return image.NewYCbCr(bounds, i.SubsampleRatio) } panic("Unknown image type") }
func TestEncodeImplicitConfigSize(t *testing.T) { // For backwards compatibility for Go 1.4 and earlier code, the Config // field is optional, and if zero, the width and height is implied by the // first (and in this case only) frame's width and height. // // A Config only specifies a width and height (two integers) while an // image.Image's Bounds method returns an image.Rectangle (four integers). // For a gif.GIF, the overall bounds' top-left point is always implicitly // (0, 0), and any frame whose bounds have a negative X or Y will be // outside those overall bounds, so encoding should fail. for _, lowerBound := range []int{-1, 0, 1} { images := []*image.Paletted{ image.NewPaletted(image.Rect(lowerBound, lowerBound, 4, 4), palette.Plan9), } g := &GIF{ Image: images, Delay: make([]int, len(images)), } err := EncodeAll(ioutil.Discard, g) if lowerBound >= 0 { if err != nil { t.Errorf("lowerBound=%d: %v", lowerBound, err) } } else { if err == nil { t.Errorf("lowerBound=%d: got nil error, want non-nil", lowerBound) } } } }
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 }
// Encode writes the Image m to w in GIF format. func Encode(w io.Writer, m image.Image, o *Options) error { // Check for bounds and size restrictions. b := m.Bounds() if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 { return errors.New("gif: image is too large to encode") } opts := Options{} if o != nil { opts = *o } if opts.NumColors < 1 || 256 < opts.NumColors { opts.NumColors = 256 } if opts.Drawer == nil { opts.Drawer = draw.FloydSteinberg } pm, ok := m.(*image.Paletted) if !ok || len(pm.Palette) > opts.NumColors { // TODO: Pick a better sub-sample of the Plan 9 palette. pm = image.NewPaletted(b, palette.Plan9[:opts.NumColors]) if opts.Quantizer != nil { pm.Palette = opts.Quantizer.Quantize(make(color.Palette, 0, opts.NumColors), m) } opts.Drawer.Draw(pm, b, m, image.ZP) } return EncodeAll(w, &GIF{ Image: []*image.Paletted{pm}, Delay: []int{0}, TransparentIndices: []int{-1}, }) }
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 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 }
func (qz *quantizer) Paletted() *image.Paletted { cp := make(color.Palette, len(qz.cs)) pi := image.NewPaletted(qz.img.Bounds(), cp) for i := range qz.cs { px := qz.cs[i].px // Average values in cluster to get palette color. var rsum, gsum, bsum int64 for _, p := range px { r, g, b, _ := qz.img.At(p.x, p.y).RGBA() rsum += int64(r) gsum += int64(g) bsum += int64(b) } n64 := int64(len(px)) cp[i] = color.NRGBA64{ uint16(rsum / n64), uint16(gsum / n64), uint16(bsum / n64), 0xffff, } // set image pixels for _, p := range px { pi.SetColorIndex(p.x, p.y, uint8(i)) } } return pi }
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 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 BenchmarkEncode(b *testing.B) { b.StopTimer() bo := image.Rect(0, 0, 640, 480) rnd := rand.New(rand.NewSource(123)) // Restrict to a 256-color paletted image to avoid quantization path. palette := make(color.Palette, 256) for i := range palette { palette[i] = color.RGBA{ uint8(rnd.Intn(256)), uint8(rnd.Intn(256)), uint8(rnd.Intn(256)), 255, } } img := image.NewPaletted(image.Rect(0, 0, 640, 480), palette) for y := bo.Min.Y; y < bo.Max.Y; y++ { for x := bo.Min.X; x < bo.Max.X; x++ { img.Set(x, y, palette[rnd.Intn(256)]) } } b.SetBytes(640 * 480 * 4) b.StartTimer() for i := 0; i < b.N; i++ { Encode(ioutil.Discard, img, nil) } }
func TestEncodeMismatchDelay(t *testing.T) { images := make([]*image.Paletted, 2) for i := range images { images[i] = image.NewPaletted(image.Rect(0, 0, 5, 5), palette.Plan9) } g0 := &GIF{ Image: images, Delay: make([]int, 1), } if err := EncodeAll(ioutil.Discard, g0); err == nil { t.Error("expected error from mismatched delay and image slice lengths") } g1 := &GIF{ Image: images, Delay: make([]int, len(images)), Disposal: make([]byte, 1), } for i := range g1.Disposal { g1.Disposal[i] = DisposalNone } if err := EncodeAll(ioutil.Discard, g1); err == nil { t.Error("expected error from mismatched disposal and image slice lengths") } }
func BenchmarkCopyImagePaletted(b *testing.B) { img := image.NewPaletted(image.Rect(0, 0, 4096, 4096), palette.Plan9) b.ResetTimer() for i := 0; i < b.N; i++ { CopyImage(img) } }
func TestEncodeNonZeroMinPoint(t *testing.T) { points := []image.Point{ image.Point{-8, -9}, image.Point{-4, -4}, image.Point{-3, +3}, image.Point{+0, +0}, image.Point{+2, +2}, } for _, p := range points { src := image.NewPaletted(image.Rectangle{Min: p, Max: p.Add(image.Point{6, 6})}, palette.Plan9) var buf bytes.Buffer if err := Encode(&buf, src, nil); err != nil { t.Errorf("p=%v: Encode: %v", p, err) continue } m, err := Decode(&buf) if err != nil { t.Errorf("p=%v: Decode: %v", p, err) continue } if got, want := m.Bounds(), image.Rect(0, 0, 6, 6); got != want { t.Errorf("p=%v: got %v, want %v", p, got, want) } } }
func main() { const ( // Mandelbrot set. xmin, xmax, ymin, ymax = -2.1, +1.1, -1.4, +1.4 // Antenna zoom in. // xmin, xmax, ymin, ymax = -1.4865, -1.4705, -0.007, +0.007 // Second antenna zoom in. // xmin, xmax, ymin, ymax = -1.483885, -1.483805, -3.5e-5, +3.5e-5 width, height = 2240, 1960 ) img := image.NewPaletted(image.Rect(0, 0, width/2, height/2), palette.Plan9) for py := 0; py < height; py += 2 { y0 := float64(py)/height*(ymax-ymin) + ymin y1 := float64(py+1)/height*(ymax-ymin) + ymin for px := 0; px < width; px += 2 { x0 := float64(px)/width*(xmax-xmin) + xmin x1 := float64(px+1)/width*(xmax-xmin) + xmin colorIdx := uint8((mandelbrot(complex(x0, y0))+ mandelbrot(complex(x0, y1))+ mandelbrot(complex(x1, y0))+ mandelbrot(complex(x1, y1)))/4.0 + 0.5) img.SetColorIndex(px/2, py/2, colorIdx) } } png.Encode(os.Stdout, img) // NOTE: ignoring errors }
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 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) }
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) }
func ExampleDrawer_floydSteinberg() { const width = 130 const height = 50 im := image.NewGray(image.Rectangle{Max: image.Point{X: width, Y: height}}) for x := 0; x < width; x++ { for y := 0; y < height; y++ { dist := math.Sqrt(math.Pow(float64(x-width/2), 2)/3+math.Pow(float64(y-height/2), 2)) / (height / 1.5) * 255 var gray uint8 if dist > 255 { gray = 255 } else { gray = uint8(dist) } im.SetGray(x, y, color.Gray{Y: 255 - gray}) } } pi := image.NewPaletted(im.Bounds(), []color.Color{ color.Gray{Y: 255}, color.Gray{Y: 160}, color.Gray{Y: 70}, color.Gray{Y: 35}, color.Gray{Y: 0}, }) draw.FloydSteinberg.Draw(pi, im.Bounds(), im, image.ZP) shade := []string{" ", "░", "▒", "▓", "█"} for i, p := range pi.Pix { fmt.Print(shade[p]) if (i+1)%width == 0 { fmt.Print("\n") } } }
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 }
// 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) }