// NewImage returns a new image canvas // that draws to the given image. The // minimum point of the given image // should probably be 0,0. func NewImage(img draw.Image, name string) (*Canvas, error) { w := float64(img.Bounds().Max.X - img.Bounds().Min.X) h := float64(img.Bounds().Max.Y - img.Bounds().Min.Y) X, err := xgbutil.NewConn() if err != nil { return nil, err } keybind.Initialize(X) ximg := xgraphics.New(X, image.Rect(0, 0, int(w), int(h))) err = ximg.CreatePixmap() if err != nil { return nil, err } painter := NewPainter(ximg) gc := draw2dimg.NewGraphicContextWithPainter(ximg, painter) gc.SetDPI(dpi) gc.Scale(1, -1) gc.Translate(0, -h) wid := ximg.XShowExtra(name, true) go func() { xevent.Main(X) }() c := &Canvas{ Canvas: vgimg.NewWith(vgimg.UseImageWithContext(img, gc)), x: X, ximg: ximg, wid: wid, } vg.Initialize(c) return c, nil }
func genTwitterGif(tweets []anaconda.Tweet, username string, tid int64) (string, error) { wid := 440 height := 220 colList := color.Palette{ color.RGBA{0x00, 0x00, 0x00, 0xFF}, color.RGBA{0xFF, 0x33, 0x33, 0xFF}, color.RGBA{0x33, 0xFF, 0x33, 0xFF}, color.RGBA{0x33, 0x33, 0xFF, 0xFF}, color.RGBA{0xFF, 0xFF, 0x33, 0xFF}, color.RGBA{0xFF, 0x33, 0xFF, 0xFF}, color.RGBA{0x33, 0xFF, 0xFF, 0xFF}, } newList := []*image.Paletted{} delayList := []int{} fireworkList := []FireWork{} disposalList := []byte{} draw2d.SetFontFolder("static") for i := range tweets { f := genFireworkFromTweet(tweets, i, float64(wid), float64(height)) fireworkList = append(fireworkList, f) } boundRect := image.Rect(0, 0, wid, height) for len(fireworkList) > 0 { rawImg := image.NewRGBA(boundRect) // TODO :: Create Custom Painter // which does blend up painter := raster.NewRGBAPainter(rawImg) gc := draw2dimg.NewGraphicContextWithPainter(rawImg, painter) gc.SetFontData(draw2d.FontData{ Name: "Roboto", }) gc.SetFontSize(8) gc.Clear() gc.SetFillColor(colList[0]) gc.MoveTo(0, 0) gc.LineTo(0, float64(height)) gc.LineTo(float64(wid), float64(height)) gc.LineTo(float64(wid), 0) gc.Close() gc.Fill() newFList := []FireWork{} for _, f := range fireworkList { if f.d > 0 { f.d -= 1.0 } else { gc.SetFillColor(colList[f.colID]) gc.SetStrokeColor(colList[f.colID]) gc.MoveTo(f.x, f.y) gc.FillStringAt(f.text, f.x-4, f.y+4) gc.MoveTo(f.x, f.y) gc.SetLineWidth(f.sz) gc.LineTo(f.x-f.dx, f.y-f.dy) for ns := 1.0; ns < f.sz; ns += 1.0 { gc.SetLineWidth(f.sz - ns) gc.LineTo(f.x-f.dx*ns*0.2, f.y-f.dy*ns*0.2) } gc.Stroke() f.x += f.dx f.y += f.dy f.t -= 1.0 f.dy += 0.3 } if f.t > 0 { newFList = append(newFList, f) } else if len(f.bundle) > 0 { for _, subF := range f.bundle { subF.x += f.x subF.y += f.y newFList = append(newFList, subF) } } } fireworkList = newFList // Make Pallette Image newImg := image.NewPaletted(boundRect, colList) for x := 0; x < wid; x++ { for y := 0; y < height; y++ { newImg.SetColorIndex(x, y, uint8(colList.Index(rawImg.At(x, y)))) } } // Add Lists if len(newList) == 0 { disposalList = append(disposalList, gif.DisposalNone) } else { disposalList = append(disposalList, gif.DisposalPrevious) } newList = append(newList, newImg) delayList = append(delayList, 10) } log.Println("Saving gif with ", len(newList), " frames") gifData := gif.GIF{ Image: newList, Delay: delayList, Disposal: disposalList, LoopCount: -1, BackgroundIndex: 0, Config: image.Config{ ColorModel: colList, Width: wid, Height: height, }, } fn := MakeGifFilename(username, tid) f, e := os.Create(fn) if e != nil { log.Println(e) return "", e } e = gif.EncodeAll(f, &gifData) if e != nil { log.Println(e) return "", e } return fn, nil }