Skip to content

Instantly share code, notes, and snippets.

@justinfx
Created May 23, 2016 13:12
Show Gist options
  • Save justinfx/ebc979f1ba5fb610d6dd290ca1d7917f to your computer and use it in GitHub Desktop.
Save justinfx/ebc979f1ba5fb610d6dd290ca1d7917f to your computer and use it in GitHub Desktop.
golang gif test server - fork of https://github.com/moddyz/gifserver
package main
import (
"bytes"
"fmt"
"image"
"image/gif"
"net/http"
"github.com/gin-gonic/gin"
"github.com/justinfx/openimageigo"
)
var cache map[string]*gif.GIF
func serveGif(c *gin.Context, g *gif.GIF) {
var b bytes.Buffer
gif.EncodeAll(&b, g)
c.Data(200, "image/gif", b.Bytes())
}
func previewHandler(c *gin.Context) {
key := c.Param("key")
g, ok := cache[key]
if ok == true {
fmt.Printf("Found cache for: %v\n", key)
serveGif(c, g)
return
}
src, err := oiio.NewImageBufPath(key)
if err != nil {
err = fmt.Errorf("Cannot read gif: %v\n", err)
c.AbortWithError(http.StatusBadRequest, err)
return
}
// Make smaller
roi := oiio.NewROIRegion2D(0, 512, 0, 512)
dst := oiio.NewImageBuf()
oiio.Resize(dst, src, oiio.AlgoOpts{ROI: roi})
src = dst
// Copy to a new buffer, with alpha
spec := src.Spec()
spec = oiio.NewImageSpecSize(spec.Width(), spec.Height(), 4, oiio.TypeUint8)
dst, _ = oiio.NewImageBufSpec(spec)
err = dst.CopyPixels(src)
if err != nil {
c.AbortWithError(500, fmt.Errorf("Failed to process gif (1): %v", err))
return
}
// Grab the 8bit pixels
pix, err := dst.GetPixels(oiio.TypeUint8)
if err != nil {
c.AbortWithError(500, fmt.Errorf("Failed to process gif (2): %v", err))
return
}
// Manually construct an RGB image with pixels
img := image.NewRGBA(image.Rect(0, 0, spec.Width(), spec.Height()))
img.Pix = pix.([]uint8)
img.Stride = spec.ScanlineBytes(false)
// Encode to GIF
var buf bytes.Buffer
err = gif.Encode(&buf, img, &gif.Options{256, nil, nil})
if err != nil {
c.AbortWithError(500, fmt.Errorf("Failed to encode gif: %v", err))
return
}
// Decode from GIF
g, err = gif.DecodeAll(&buf)
if err != nil {
err = fmt.Errorf("Cannot read gif %v\n", err)
c.AbortWithError(500, err)
return
}
cache[key] = g
serveGif(c, g)
fmt.Printf("Set cache for: %v\n", key)
}
func main() {
cache = make(map[string]*gif.GIF)
r := gin.Default()
r.GET("/preview/:key", previewHandler)
r.Run()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment