Skip to content

Instantly share code, notes, and snippets.

@aarti
Created January 6, 2017 02:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aarti/a6b6003e8ad039ee457fc47d8702cbf0 to your computer and use it in GitHub Desktop.
Save aarti/a6b6003e8ad039ee457fc47d8702cbf0 to your computer and use it in GitHub Desktop.
Convert Gif's to PingPong Gif's
package main
import (
"bytes"
"image"
"image/gif"
"io/ioutil"
"log"
"net/http"
"sort"
"strconv"
)
var urls = []string{
"https://j.gifs.com/lOEomr.gif",
"https://j.gifs.com/k5XnlE.gif",
"https://j.gifs.com/g5MjG3.gif",
"https://j.gifs.com/98YwyZ.gif",
"https://j.gifs.com/Wnoylv.gif",
"https://j.gifs.com/3lVnpx.gif",
"https://j.gifs.com/VmnxkW.gif",
"https://j.gifs.com/Q1gp2L.gif",
"https://j.gifs.com/LgWk2A.gif",
"https://media.giphy.com/media/KaMqnPFHqAesw/source.gif",
}
var c = make(chan orderedGifs, 10)
var giferr = make(chan error, 10)
type orderedGifs struct {
sourceurl string
destFile string
order int
}
// ByOrder implements the sort.Interface for []orderedGifs based on
// the order field.
type ByOrder []orderedGifs
func (a ByOrder) Len() int { return len(a) }
func (a ByOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByOrder) Less(i, j int) bool { return a[i].order < a[j].order }
func main() {
maxLen := len(urls)
for i := 0; i < maxLen; i++ {
log.Printf("Processing %d %s", i, urls[i])
go pingpong(i, urls[i])
}
count := 0
orderedGifs := []orderedGifs{}
for {
select {
case err := <-giferr:
count++
log.Printf("Error processing %v", err)
case s := <-c:
count++
orderedGifs = append(orderedGifs, s)
log.Printf("Finished processing %s", s.destFile)
}
if count == maxLen {
break
}
}
close(c)
close(giferr)
sort.Sort(ByOrder(orderedGifs))
log.Printf("%d urls submitted %d processed", len(urls), len(orderedGifs))
for i := 0; i < len(orderedGifs); i++ {
log.Printf("Gif order: %d %s %s", orderedGifs[i].order, orderedGifs[i].sourceurl, orderedGifs[i].destFile)
}
}
func pingpong(i int, url string) {
destFile := "dest/" + strconv.Itoa(i) + ".gif"
sourceFile := "source/" + strconv.Itoa(i) + ".gif"
resp, err := http.Get(url)
if err != nil || resp.StatusCode != 200 {
giferr <- err
return
}
source, err := gif.DecodeAll(resp.Body)
if err != nil {
giferr <- err
return
}
buf := new(bytes.Buffer)
err = gif.EncodeAll(buf, source)
if err != nil {
giferr <- err
return
}
err = ioutil.WriteFile(sourceFile, buf.Bytes(), 0644)
if err != nil {
giferr <- err
return
}
dest := &gif.GIF{
BackgroundIndex: source.BackgroundIndex,
Config: image.Config{
Width: source.Config.Width,
Height: source.Config.Height,
ColorModel: source.Config.ColorModel,
},
LoopCount: source.LoopCount,
}
for i := 0; i < len(source.Image)-1; i++ {
dest.Image = append(dest.Image, source.Image[i])
dest.Delay = append(dest.Delay, source.Delay[i])
dest.Disposal = append(dest.Disposal, source.Disposal[i])
}
finalDelay := source.Delay[len(source.Delay)-1]
for i := len(source.Image) - 2; i > 0; i-- {
dest.Image = append(dest.Image, source.Image[i])
dest.Delay = append(dest.Delay, source.Delay[i])
dest.Disposal = append(dest.Disposal, gif.DisposalPrevious)
}
dest.Delay[len(dest.Delay)-1] = finalDelay
buf = new(bytes.Buffer)
err = gif.EncodeAll(buf, dest)
if err != nil {
giferr <- err
return
}
ioutil.WriteFile(destFile, buf.Bytes(), 0644)
c <- orderedGifs{destFile: destFile, order: i, sourceurl: url}
}
aarti@classyhacker:~/dev/interview/gifs.com$ go run make_gif.go
2016/12/30 16:25:07 Processing 0 https://j.gifs.com/lOEomr.gif
2016/12/30 16:25:07 Processing 1 https://j.gifs.com/k5XnlE.gif
2016/12/30 16:25:07 Processing 2 https://j.gifs.com/g5MjG3.gif
2016/12/30 16:25:07 Processing 3 https://j.gifs.com/98YwyZ.gif
2016/12/30 16:25:07 Processing 4 https://j.gifs.com/Wnoylv.gif
2016/12/30 16:25:07 Processing 5 https://j.gifs.com/3lVnpx.gif
2016/12/30 16:25:07 Processing 6 https://j.gifs.com/VmnxkW.gif
2016/12/30 16:25:07 Processing 7 https://j.gifs.com/Q1gp2L.gif
2016/12/30 16:25:07 Processing 8 https://j.gifs.com/LgWk2A.gif
2016/12/30 16:25:07 Processing 9 https://media.giphy.com/media/KaMqnPFHqAesw/source.gif
2016/12/30 16:25:08 Finished processing dest/9.gif
2016/12/30 16:25:15 Finished processing dest/8.gif
2016/12/30 16:25:15 Error processing gif: too much image data
2016/12/30 16:25:15 Finished processing dest/4.gif
2016/12/30 16:25:16 Finished processing dest/0.gif
2016/12/30 16:25:16 Finished processing dest/5.gif
2016/12/30 16:25:17 Finished processing dest/2.gif
2016/12/30 16:25:17 Finished processing dest/3.gif
2016/12/30 16:25:17 Finished processing dest/6.gif
2016/12/30 16:25:18 Finished processing dest/7.gif
2016/12/30 16:25:18 10 urls submitted 9 processed
2016/12/30 16:25:18 Gif order: 0 https://j.gifs.com/lOEomr.gif dest/0.gif
2016/12/30 16:25:18 Gif order: 2 https://j.gifs.com/g5MjG3.gif dest/2.gif
2016/12/30 16:25:18 Gif order: 3 https://j.gifs.com/98YwyZ.gif dest/3.gif
2016/12/30 16:25:18 Gif order: 4 https://j.gifs.com/Wnoylv.gif dest/4.gif
2016/12/30 16:25:18 Gif order: 5 https://j.gifs.com/3lVnpx.gif dest/5.gif
2016/12/30 16:25:18 Gif order: 6 https://j.gifs.com/VmnxkW.gif dest/6.gif
2016/12/30 16:25:18 Gif order: 7 https://j.gifs.com/Q1gp2L.gif dest/7.gif
2016/12/30 16:25:18 Gif order: 8 https://j.gifs.com/LgWk2A.gif dest/8.gif
2016/12/30 16:25:18 Gif order: 9 https://media.giphy.com/media/KaMqnPFHqAesw/source.gif dest/9.gif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment