Last active
February 9, 2018 12:19
-
-
Save feliperohdee/795dde0bcf8a7f65d1d35cbd478f419d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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