Skip to content

Instantly share code, notes, and snippets.

@feliperohdee
Last active February 9, 2018 12:19
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 feliperohdee/795dde0bcf8a7f65d1d35cbd478f419d to your computer and use it in GitHub Desktop.
Save feliperohdee/795dde0bcf8a7f65d1d35cbd478f419d to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"encoding/base64"
"errors"
"github.com/aws/aws-lambda-go/lambda"
"github.com/disintegration/imaging"
"github.com/nickalie/go-webpbin"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"
"pointers/files"
"strconv"
"strings"
"time"
)
type Image struct {
Buffer []byte
Extension string
Type string
}
var srcRequiredError = errors.New("src is required.")
func GetImage(url string) (*Image, error) {
response, err := http.Get(url)
defer response.Body.Close()
if err != nil {
return &Image{}, err
}
Type := response.Header.Get("content-type")
Extension := strings.Split(Type, "/")[1]
Buffer, err := ioutil.ReadAll(response.Body)
if err != nil {
return &Image{}, err
}
return &Image{
Buffer,
Extension,
Type,
}, nil
}
type ProcessResponse struct {
img *Image
err error
}
func returnProcessError(c chan *ProcessResponse, err error) chan *ProcessResponse {
c <- &ProcessResponse{
img: &Image{},
err: err,
}
return c
}
func Process(mode string, src string, width int, height int, webp bool, c chan *ProcessResponse) chan *ProcessResponse {
if src == "" {
return returnProcessError(c, srcRequiredError)
}
file := &files.Files{}
dir := file.CreateTempDir()
defer file.CleanTempDir()
src, err := url.QueryUnescape(src)
if err != nil {
return returnProcessError(c, err)
}
imgSrc, err := GetImage(src)
if err != nil {
return returnProcessError(c, err)
}
img, err := imaging.Decode(bytes.NewReader(imgSrc.Buffer))
if err != nil {
return returnProcessError(c, err)
}
bounds := img.Bounds()
if mode != "resize" {
bounds := img.Bounds()
if width == 0 {
width = bounds.Dx()
}
if height == 0 {
height = bounds.Dy()
}
}
switch mode {
case "fit":
img = imaging.Fit(img, width, height, imaging.Lanczos)
case "fill":
img = imaging.Fill(img, width, height, imaging.Center, imaging.Lanczos)
default:
img = imaging.CropAnchor(img, width, height, imaging.Center)
}
buf := new(bytes.Buffer)
if webp {
if err := webpbin.Encode(buf, img); err != nil {
return returnProcessError(c, err)
}
imgSrc.Type = "image/webp"
} else {
formats := map[string]imaging.Format{
".jpg": imaging.JPEG,
".jpeg": imaging.JPEG,
".png": imaging.PNG,
".tif": imaging.TIFF,
".tiff": imaging.TIFF,
".bmp": imaging.BMP,
".gif": imaging.GIF,
}
format, ok := formats[imgSrc.Extension]
if !ok {
return &Image{}, imaging.ErrUnsupportedFormat
}
if err := imaging.Encode(buf, img, format); err != nil {
return &Image{}, err
}
if err != nil {
return returnProcessError(c, err)
}
}
c <- &ProcessResponse{
img: &Image{
Type: imgSrc.Type,
Extension: imgSrc.Extension,
Buffer: buf.Bytes(),
},
err: nil,
}
return c
}
type Request struct {
Mode string `json:"mode"`
Src string `json:"src"`
Width int `json:"width"`
Height int `json:"height"`
WebP bool `json:"webp"`
}
type Response struct {
Body string `json:"body"`
Base64Encoded bool `json:"base64Encoded"`
Headers map[string]string `json:"headers"`
}
func Handler(request Request) (Response, error) {
c := make(chan *ProcessResponse)
go Process(request.Mode, request.Src, request.Width, request.Height, request.WebP, c)
process := <-c
if process.err != nil {
return Response{}, process.err
}
headers := make(map[string]string)
headers["content-type"] = process.img.Type
return Response{
Body: base64.StdEncoding.EncodeToString(process.img.Buffer),
Base64Encoded: true,
Headers: headers,
}, nil
}
func main() {
isDev := os.Getenv("env") != "production"
if isDev {
response, err := Handler(Request{
Src: "https://www.google.com.br/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png",
Width: 500,
Height: 0,
})
log.Println(response, err)
} else {
lambda.Start(Handler)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment