func TestEncode(t *testing.T) { for _, filename := range []string{"cat", "matt"} { var ( err error file *os.File g *gif.GIF ) file, err = os.Open("test/" + filename + ".gif") if err != nil { t.Errorf("os.Open '%s'", err) } g, err = gif.DecodeAll(file) if err != nil { t.Errorf("DecodeAll error '%s'", err) } file, _ = ioutil.TempFile("", filename) err = EncodeAll(file, g) if err != nil { t.Errorf("EncodeAll error '%s'", err) } file.Seek(0, os.SEEK_SET) // rewind tmp file g, err = gif.DecodeAll(file) if err != nil { t.Errorf("DecodeAll error '%s'", err) } } }
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 TestSaveGifIntoFileSystem(t *testing.T) { var user = User{Name: "jinzhu"} if avatar, err := os.Open("test/test.gif"); err == nil { var frames int if g, err := gif.DecodeAll(avatar); err == nil { frames = len(g.Image) } avatar.Seek(0, 0) user.Avatar.Scan(avatar) if err := db.Save(&user).Error; err == nil { if _, err := os.Stat(path.Join("public", user.Avatar.URL())); err != nil { t.Errorf("should find saved user avatar") } var newUser User db.First(&newUser, user.ID) newUser.Avatar.Scan(`{"CropOptions": {"small1": {"X": 5, "Y": 5, "Height": 10, "Width": 20}, "small2": {"X": 0, "Y": 0, "Height": 10, "Width": 20}}, "Crop": true}`) db.Save(&newUser) if newUser.Avatar.URL() == user.Avatar.URL() { t.Errorf("url should be different after crop") } file, err := os.Open(path.Join("public", newUser.Avatar.URL("small1"))) if err != nil { t.Errorf("Failed open croped image") } if g, err := gif.DecodeAll(file); err == nil { if g.Config.Width != 20 || g.Config.Height != 10 { t.Errorf("gif should be croped successfully") } for _, image := range g.Image { if image.Rect.Dx() != 20 || image.Rect.Dy() != 10 { t.Errorf("gif's frames should be croped successfully, but it is %vx%v", image.Rect.Dx(), image.Rect.Dy()) } } if frames != len(g.Image) || frames == 0 { t.Errorf("Gif's frames should be same") } } else { t.Errorf("Failed to decode croped gif image") } } else { t.Errorf("should saved user successfully") } } else { panic("file doesn't exist") } }
func main() { if len(os.Args) != 2 { log.Fatalf("Missing the required filename parameter\n") } filename := os.Args[1] var wg sync.WaitGroup fh, err := os.Open(filename) if err != nil { log.Fatalf("Failed to open '%s' - {Error: %v}\n", filename, err) } gifs, err := gif.DecodeAll(fh) if err != nil { log.Fatalf("Failed to decode '%s' - {Error: %v}\n", filename, err) } wg.Add(len(gifs.Image)) for idx, image := range gifs.Image { newFileName := fmt.Sprintf("%s.%d.png", filename, idx) go writeImage(&wg, image, newFileName) } wg.Wait() }
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 main() { flag.Parse() if len(flag.Args()) == 0 || config.Help { flag.Usage() os.Exit(1) } f, err := openFile(flag.Args()[0]) exitOnError(err) g, err := gif.DecodeAll(f) exitOnError(err) state := State{ Gif: g, Config: config, } gc := GameCore{ TickTime: time.Millisecond * 50, OnInit: state.OnInit, OnEvent: state.OnEvent, OnTick: state.OnTick, } err = gc.Run() exitOnError(err) }
func NewAnim(r io.Reader) *Anim { a := new(Anim) g, err := gif.DecodeAll(r) if err != nil { log.Fatal(err) } a.raw = g a.frameCount = len(g.Image) log.Printf("Loaded GIF containing %d frames.\n", a.frameCount) a.frames = make([]image.Image, a.frameCount) a.elapsed = make([]int, a.frameCount) for i := 0; i < a.frameCount; i++ { // Generate an Image for each frame p := g.Image[i] a.frames[i] = p.SubImage(p.Rect) // The frame delay is specified in 100ths of a second, // so multiply by 10 to get milliseconds. frameLength := g.Delay[i] * 10 frameStart := 0 if i > 0 { frameStart = a.elapsed[i-1] + frameLength } a.elapsed[i] = frameStart a.duration += frameLength } log.Printf("Total duration: %.2fs\n", float32(a.duration)/1000.0) return a }
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 GetInfoForBytes(filename string, data []byte) (*FileInfo, *AppError) { size := len(data) var mimeType string extension := filepath.Ext(filename) isImage := IsFileExtImage(extension) if isImage { mimeType = GetImageMimeType(extension) } else { mimeType = mime.TypeByExtension(extension) } hasPreviewImage := isImage if mimeType == "image/gif" { // just show the gif itself instead of a preview image for animated gifs if gifImage, err := gif.DecodeAll(bytes.NewReader(data)); err != nil { return nil, NewLocAppError("GetInfoForBytes", "model.file_info.get.gif.app_error", nil, "filename="+filename) } else { hasPreviewImage = len(gifImage.Image) == 1 } } return &FileInfo{ Filename: filename, Size: size, Extension: extension[1:], MimeType: mimeType, HasPreviewImage: hasPreviewImage, }, nil }
func main() { file, err := os.Open("pacman.gif") if err != nil { log.Fatalf("Error opening file: %s\n", err) } g, err := gif.DecodeAll(file) if err != nil { log.Fatalf("Error decoding gif: %s\n", err) } for { for _, img := range g.Image { for x := 0; x < 40; x++ { for y := 0; y < 40; y++ { color := img.At(x, y) r, g, b, _ := color.RGBA() colorString := fmt.Sprintf("%02x%02x%02x", uint8(r), uint8(g), uint8(b)) fmt.Println(colorString) resp, err := http.Get(fmt.Sprintf("http://localhost:1234/draw?x=%d&y=%d&color=%s&layer=foize", x, y, colorString)) if err != nil { log.Fatalf("error drawing with http.Get: %s\n", err) } if resp.StatusCode != http.StatusOK { log.Fatalf("error drawing, have http status %s\n", resp.Status) } resp.Body.Close() } } time.Sleep(300 * time.Millisecond) } } }
func main() { if len(os.Args) > 1 { fn := regexp.MustCompile(".gif$") for _, v := range os.Args[1:] { f, e := os.Open(v) iserr(e) log.Println("[ Read GIF ] File=", f.Name()) gif, e := gif.DecodeAll(f) f.Close() iserr(e) log.Println("[ Create PNG ] Size=", len(gif.Image)*150, 150) dst := image.NewRGBA(image.Rect(0, 0, len(gif.Image)*150, 150)) iserr(e) log.Println("[ Slice GIF ] Size=", len(gif.Image)) for index, src := range gif.Image { b := src.Bounds() m, n := 150/2-b.Dx()/2+index*150, 150/2-b.Dy()/2 r := image.Rect(m, n, m+b.Dx(), n+b.Dy()) log.Println("GIF drawto PNG for", index) draw.Draw(dst, r, src, image.ZP, draw.Src) } log.Println("[ Write PNG ]") out, e := os.Create(fmt.Sprintf("%s.png", fn.ReplaceAllLiteralString(f.Name(), ""))) iserr(e) e = png.Encode(out, dst) iserr(e) out.Close() } log.Println("Convert Success. Press any key to exit.") var s string fmt.Scanf("%s", &s) } else { fmt.Println("Usage:", os.Args[0], "<filename>") } }
// 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 crop(filename string) { f, err := os.Open("testdata/" + filename + ".gif") if err != nil { log.Fatal(err.Error()) } defer f.Close() im, err := gif.DecodeAll(f) if err != nil { log.Fatal(err.Error()) } firstFrame := im.Image[0] imgBounds := firstFrame.Bounds() img := image.NewRGBA(imgBounds) for index, frame := range im.Image { bounds := frame.Bounds() draw.Draw(img, bounds, frame, bounds.Min, draw.Src) im.Image[index] = ImageToPaletted(img.SubImage(image.Rect( imgBounds.Min.X, imgBounds.Min.Y+imgBounds.Dy()/4, imgBounds.Max.X, imgBounds.Max.Y-imgBounds.Dy()/4))) } out, err := os.Create(filename + ".out.gif") if err != nil { log.Fatal(err.Error()) } defer out.Close() gogif.EncodeAll(out, im) }
// 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 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 main() { var startFrame int var frameCount int flag.IntVar(&startFrame, "start", 0, "frame at wich the animation should start") flag.IntVar(&frameCount, "count", 0, "amount of frames the animation should have") flag.Parse() inputFileName := flag.Arg(0) outputFileName := flag.Arg(1) in, err := os.Open(inputFileName) if err != nil { fmt.Println(err) os.Exit(1) } gifImage, err := gif.DecodeAll(in) if err != nil { log.Fatal(err) } img := gifImage.Image[0] log.Println("converting...") sim := simulation.New(img) log.Println("simulating...") for ; startFrame > 0; startFrame-- { sim = sim.Step() } if 0 == frameCount { sim, frameCount = sim.FindLooping() } log.Println("rendering...") img.Palette[0] = color.Transparent gifImage.Delay = make([]int, frameCount) gifImage.Disposal = make([]byte, frameCount) for i := range gifImage.Delay { gifImage.Delay[i] = 1 } gifImage.Image = sim.DrawAll(img, frameCount) log.Println("writing...") out, err := os.Create(outputFileName) if err != nil { fmt.Println(err) os.Exit(1) } err = gif.EncodeAll(out, gifImage) if err != nil { log.Fatal(err) } log.Println("done.") }
func readGIF(filename string) (*gif.GIF, error) { f, err := os.Open(filename) if err != nil { return nil, err } defer f.Close() return gif.DecodeAll(f) }
func makeGif(c appengine.Context, m *movie) ([]byte, error) { palette := m.palette() delay := int(100 / m.Speed) anim := gif.GIF{LoopCount: 0} for _, pix := range m.Frames { bounds := image.Rect(0, 0, m.Width*pixelsize, m.Height*pixelsize) scaled := make([]byte, bounds.Max.X*bounds.Max.Y) idx := 0 for y := 0; y < m.Height; y++ { for i := 0; i < pixelsize; i++ { for x := 0; x < m.Width; x++ { pixel := pix[x+y*m.Width] - startColorChar for j := 0; j < pixelsize; j++ { scaled[idx] = pixel idx++ } } } } img := image.Paletted{ Pix: scaled, Stride: m.Width * pixelsize, Rect: bounds, Palette: palette, } anim.Image = append(anim.Image, &img) anim.Delay = append(anim.Delay, delay) } var buf bytes.Buffer if err := gifencoder.EncodeAll(&buf, anim); err != nil { c.Errorf("can't encode gif: %v", err) return nil, err } if appengine.IsDevAppServer() { // Validate gif by decoding it r := bytes.NewReader(buf.Bytes()) size := r.Len() if _, err := gif.DecodeAll(r); err != nil { remaining := r.Len() offset := size - remaining c.Errorf("created an invalid gif: %v", err) c.Errorf("error at offset %v (%x)", offset, offset) } } return buf.Bytes(), nil }
func NewGIFManipulator(reader io.ReadSeeker, format string, image image.Image) (Manipulator, error) { if _, err := reader.Seek(0, 0); err != nil { return nil, err } g, err := gif.DecodeAll(reader) if err != nil { return nil, err } return &GIFManipulator{gif: g}, nil }
func download(url string) (*gif.GIF, error) { //log.Printf("GET %s ..", url) res, err := http.Get(url) if err != nil { return nil, err } defer res.Body.Close() if res.StatusCode != 200 { return nil, errors.New(fmt.Sprintf("error response '%d'", res.StatusCode)) } return gif.DecodeAll(res.Body) }
func main() { args := os.Args[1:] if len(args) > 2 || len(args) == 0 { showUsage() return } input := args[0] fmt.Println("Reading file", input) file, err := os.Open(input) if err != nil { fmt.Println(err) return } img, err := gif.DecodeAll(file) if err != nil { fmt.Println(err) return } reversed := new(gif.GIF) reversed.Delay = img.Delay reversed.LoopCount = img.LoopCount reversed.Image = reverse(img.Image) fmt.Println("Reversing..") var output string if len(args) == 2 { output = strings.TrimSuffix(args[1], filepath.Ext(input)) + ".gif" } else { output = strings.TrimSuffix(input, filepath.Ext(input)) + "_reversed.gif" } result, err := os.Create(output) if err != nil { fmt.Println(err) return } gif.EncodeAll(result, reversed) fmt.Println("✓ Saved", output) }
func uploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppError { file, err := imageData.Open() if err != nil { return model.NewLocAppError("uploadEmojiImage", "api.emoji.upload.open.app_error", nil, "") } defer file.Close() buf := bytes.NewBuffer(nil) io.Copy(buf, file) // make sure the file is an image and is within the required dimensions if config, _, err := image.DecodeConfig(bytes.NewReader(buf.Bytes())); err != nil { return model.NewLocAppError("uploadEmojiImage", "api.emoji.upload.image.app_error", nil, err.Error()) } else if config.Width > MaxEmojiWidth || config.Height > MaxEmojiHeight { data := buf.Bytes() newbuf := bytes.NewBuffer(nil) if info, err := model.GetInfoForBytes(imageData.Filename, data); err != nil { return err } else if info.MimeType == "image/gif" { if gif_data, err := gif.DecodeAll(bytes.NewReader(data)); err != nil { return model.NewLocAppError("uploadEmojiImage", "api.emoji.upload.large_image.gif_decode_error", nil, "") } else { resized_gif := resizeEmojiGif(gif_data) if err := gif.EncodeAll(newbuf, resized_gif); err != nil { return model.NewLocAppError("uploadEmojiImage", "api.emoji.upload.large_image.gif_encode_error", nil, "") } if err := app.WriteFile(newbuf.Bytes(), getEmojiImagePath(id)); err != nil { return err } } } else { if img, _, err := image.Decode(bytes.NewReader(data)); err != nil { return model.NewLocAppError("uploadEmojiImage", "api.emoji.upload.large_image.decode_error", nil, "") } else { resized_image := resizeEmoji(img, config.Width, config.Height) if err := png.Encode(newbuf, resized_image); err != nil { return model.NewLocAppError("uploadEmojiImage", "api.emoji.upload.large_image.encode_error", nil, "") } if err := app.WriteFile(newbuf.Bytes(), getEmojiImagePath(id)); err != nil { return err } } } } else { if err := app.WriteFile(buf.Bytes(), getEmojiImagePath(id)); err != nil { return err } } return nil }
// NewRevisitImageFromMsg constructs a RevisitImage from the // contents of a RevisitMsg func NewRevisitImageFromMsg(r *RevisitMsg) (*RevisitImage, error) { ri := &RevisitImage{ Rgbas: make([]image.RGBA, 0), Palette: make([]color.Palette, 0), Delay: make([]int, 0), LoopCount: 0, } switch r.ImageType() { case "image/jpeg", "image/png": src, _, err := image.Decode(r.ImageByteReader()) if err != nil { return nil, err } b := src.Bounds() rgba := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) draw.Draw(rgba, rgba.Bounds(), src, b.Min, draw.Src) ri.Rgbas = append(ri.Rgbas, *rgba) ri.Delay = append(ri.Delay, 0) ri.LoopCount = 0 ri.ImgType = r.ImageType() return ri, nil case "image/gif": gifs, err := gif.DecodeAll(r.ImageByteReader()) if err != nil { return nil, err } for _, src := range gifs.Image { b := src.Bounds() rgba := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) draw.Draw(rgba, rgba.Bounds(), src, b.Min, draw.Src) ri.Rgbas = append(ri.Rgbas, *rgba) ri.Palette = append(ri.Palette, src.Palette) ri.Delay = append(ri.Delay, 0) } ri.LoopCount = gifs.LoopCount ri.ImgType = r.ImageType() return ri, nil default: return nil, errors.New("invalid image type") } }
func main() { out, err := os.Create("./output.gif") if err != nil { fmt.Println(err) os.Exit(1) } dir, _ := ioutil.ReadDir(".") var imgs []*image.Paletted for _, file := range dir { switch ext := path.Ext(file.Name()); ext { case ".jpg": f, _ := os.Open(file.Name()) img, _ := jpeg.Decode(f) var opt gif.Options opt.NumColors = 256 buf := new(bytes.Buffer) gif.Encode(buf, img, &opt) g, _ := gif.DecodeAll(buf) imgs = append(imgs, g.Image[0]) default: fmt.Println(ext) } } g := new(gif.GIF) g.Image = imgs var opt gif.Options opt.NumColors = 256 g.Delay = []int{100, 100, 100} g.LoopCount = 1000 err = gif.EncodeAll(out, g) if err != nil { fmt.Println(err) os.Exit(1) } fmt.Println("Generated image to output.gif \n") }
func main() { dir, _ := ioutil.ReadDir(".") var imgs []*image.Paletted for _, file := range dir { f, _ := os.Open(file.Name()) defer f.Close() if ext := path.Ext(file.Name()); ext != ".jpg" && ext != ".JPG" && ext != ".jpeg" && ext != ".png" { fmt.Printf("File not an image: %s\n", file.Name()) } else { img, err := rs.ResizePixels(f, 400, 400) if err != nil { fmt.Println(err) } var opt gif.Options opt.NumColors = 256 buf := new(bytes.Buffer) gif.Encode(buf, img, &opt) g, _ := gif.DecodeAll(buf) imgs = append(imgs, g.Image[0]) } } g := new(gif.GIF) g.Image = imgs g.Delay = evenDelay(100, len(g.Image)) g.LoopCount = 1000 var opt gif.Options opt.NumColors = 256 out, err := os.Create("./output.gif") if err != nil { fmt.Println(err) os.Exit(1) } err = gif.EncodeAll(out, g) if err != nil { fmt.Println(err) os.Exit(1) } fmt.Println("Generated image to output.gif \n") }
func TestResizeEmoji(t *testing.T) { // try to resize a jpeg image within MaxEmojiWidth and MaxEmojiHeight small_img_data := createTestJpeg(t, MaxEmojiWidth, MaxEmojiHeight) if small_img, _, err := image.Decode(bytes.NewReader(small_img_data)); err != nil { t.Fatal("failed to decode jpeg bytes to image.Image") } else { resized_img := resizeEmoji(small_img, small_img.Bounds().Dx(), small_img.Bounds().Dy()) if resized_img.Bounds().Dx() > MaxEmojiWidth || resized_img.Bounds().Dy() > MaxEmojiHeight { t.Fatal("resized jpeg width and height should not be greater than MaxEmojiWidth or MaxEmojiHeight") } if resized_img != small_img { t.Fatal("should've returned small_img itself") } } // try to resize a jpeg image jpeg_data := createTestJpeg(t, 256, 256) if jpeg_img, _, err := image.Decode(bytes.NewReader(jpeg_data)); err != nil { t.Fatal("failed to decode jpeg bytes to image.Image") } else { resized_jpeg := resizeEmoji(jpeg_img, jpeg_img.Bounds().Dx(), jpeg_img.Bounds().Dy()) if resized_jpeg.Bounds().Dx() > MaxEmojiWidth || resized_jpeg.Bounds().Dy() > MaxEmojiHeight { t.Fatal("resized jpeg width and height should not be greater than MaxEmojiWidth or MaxEmojiHeight") } } // try to resize a png image png_data := createTestJpeg(t, 256, 256) if png_img, _, err := image.Decode(bytes.NewReader(png_data)); err != nil { t.Fatal("failed to decode png bytes to image.Image") } else { resized_png := resizeEmoji(png_img, png_img.Bounds().Dx(), png_img.Bounds().Dy()) if resized_png.Bounds().Dx() > MaxEmojiWidth || resized_png.Bounds().Dy() > MaxEmojiHeight { t.Fatal("resized png width and height should not be greater than MaxEmojiWidth or MaxEmojiHeight") } } // try to resize an animated gif gif_data := createTestAnimatedGif(t, 256, 256, 10) if gif_img, err := gif.DecodeAll(bytes.NewReader(gif_data)); err != nil { t.Fatal("failed to decode gif bytes to gif.GIF") } else { resized_gif := resizeEmojiGif(gif_img) if resized_gif.Config.Width > MaxEmojiWidth || resized_gif.Config.Height > MaxEmojiHeight { t.Fatal("resized gif width and height should not be greater than MaxEmojiWidth or MaxEmojiHeight") } if len(resized_gif.Image) != len(gif_img.Image) { t.Fatal("resized gif should have the same number of frames as original gif") } } }
func main() { inputFileName := os.Args[1] outputFileName := os.Args[2] in, err := os.Open(inputFileName) if err != nil { fmt.Println(err) os.Exit(1) } gifImage, err := gif.DecodeAll(in) if err != nil { log.Fatal(err) } img := gifImage.Image[0] log.Println("converting...") simulation := NewSimulation(img) log.Println("simulating...") var frameCount int simulation, frameCount = simulation.FindLooping() log.Println("rendering...") img.Palette[0] = color.Transparent gifImage.Delay = make([]int, frameCount) gifImage.Disposal = make([]byte, frameCount) for i := range gifImage.Delay { gifImage.Delay[i] = 1 } gifImage.Image = simulation.DrawAll(img, frameCount) log.Println("writing...") out, err := os.Create(outputFileName) if err != nil { fmt.Println(err) os.Exit(1) } err = gif.EncodeAll(out, gifImage) if err != nil { log.Fatal(err) } log.Println("done.") }
// Image Handler // Reads the stored GIF & overlay for the authenticated user and returns a new GIF with the overlay copied onto each frame of the input GIF func imageHandler(w http.ResponseWriter, r *http.Request) { token, _ := jwt.ParseFromRequest(r, hmacKeyFunc) issuer := token.Claims["iss"].(string) gfFile, err1 := os.Open(getFileName("gif:" + issuer)) overlayFile, err2 := os.Open(getFileName("overlay:" + issuer)) if err1 != nil || err2 != nil { sendResponse(w, 400, map[string]string{ "error": "Error while reading images", }) return } // Decode images dst, err1 := gif.DecodeAll(gfFile) src, _, err2 := image.Decode(overlayFile) if err1 != nil || err2 != nil { sendResponse(w, 400, map[string]string{ "error": "Error while decoding images", }) return } // Create location for the draw pt := new(image.Point) x, err := strconv.Atoi(r.URL.Query().Get("x")) if err != nil { x = 0 } y, err := strconv.Atoi(r.URL.Query().Get("y")) if err != nil { y = 0 } pt.X = x pt.Y = y // Draw the overlay over each frame of the GIF for _, frame := range dst.Image { draw.Draw(frame, frame.Bounds(), src, *pt, draw.Over) } // Encode image to base64 buffer := new(bytes.Buffer) gif.EncodeAll(buffer, dst) fmt.Fprint(w, base64.StdEncoding.EncodeToString(buffer.Bytes())) }
func main() { var err error if cursorImage, err = ebiten.NewImage(4, 4, ebiten.FilterNearest); err != nil { log.Fatal(err) } cursorImage.Fill(color.White) var speed, scale, width, height int flag.IntVar(&speed, "speed", 15, "simulation steps per second") flag.IntVar(&scale, "scale", 16, "pixel scale factor") flag.IntVar(&width, "width", 64, "width of the simulation") flag.IntVar(&height, "height", 64, "height of the simulation") flag.Parse() flag.Args() cursorPosition = image.Point{width / 2, height / 2} simulationTimer = time.Tick(time.Second / time.Duration(speed)) if flag.NArg() == 1 { inputFileName := flag.Arg(0) in, err := os.Open(inputFileName) if err != nil { fmt.Println(err) os.Exit(1) } gifImage, err := gif.DecodeAll(in) if err != nil { log.Fatal(err) } simulationImage = gifImage.Image[0] simulationImage.Palette[0] = color.Transparent } else { p := color.Palette{ color.Black, color.RGBA{0x88, 0, 0, 0xFF}, color.RGBA{0xFF, 0, 0, 0xFF}, color.RGBA{0xFF, 0x22, 0, 0xFF}, color.RGBA{0xFF, 0x44, 0, 0xFF}, color.RGBA{0xFF, 0x66, 0, 0xFF}, color.RGBA{0xFF, 0x88, 0, 0xFF}, color.RGBA{0xFF, 0xAA, 0, 0xFF}, } simulationImage = image.NewPaletted(image.Rect(0, 0, width, height), p) } reloadSimulation() if err := ebiten.Run(update, simulationImage.Bounds().Dx(), simulationImage.Bounds().Dy(), scale, "Wired Logic"); err != nil { log.Fatal(err) } }
func LoadGIF(path string) (imgs []image.Image, err error) { f, e := os.Open(path) if e != nil { return nil, e } GIF, e := gif.DecodeAll(f) if e != nil { return nil, e } imgs = make([]image.Image, len(GIF.Image)) for i, img := range GIF.Image { imgs[i] = img } return imgs, nil }