From 9518dc2f1a36b745f92f5ffaf8c885deae82bf72 Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Sat, 14 Jan 2017 19:26:45 -0800 Subject: [PATCH] Add PNG and JPEG to WebP transcoding WebP lossy mode offers up to 30% better compression than JPEG. --- README.md | 2 +- transcoder/jpeg.go | 16 ++++++++++++++-- transcoder/png.go | 15 +++++++++++++-- transcoder/util.go | 15 +++++++++++++++ 4 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 transcoder/util.go diff --git a/README.md b/README.md index 7505c22..833b429 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Features: - gzip compression - transcode animated gifs to static images - transcode jpeg images to desired quality using libjpeg -- transcode png images +- transcode PNG and JPEG images to WebP - html/css/js minification diff --git a/transcoder/jpeg.go b/transcoder/jpeg.go index 1ae17f8..6dafe28 100644 --- a/transcoder/jpeg.go +++ b/transcoder/jpeg.go @@ -2,6 +2,7 @@ package transcoder import ( "github.com/barnacs/compy/proxy" + "github.com/chai2010/webp" "github.com/pixiv/go-libjpeg/jpeg" "net/http" ) @@ -26,8 +27,19 @@ func (t *Jpeg) Transcode(w *proxy.ResponseWriter, r *proxy.ResponseReader, heade if err != nil { return err } - if err = jpeg.Encode(w, img, t.encOptions); err != nil { - return err + + if SupportsWebP(headers) { + options := webp.Options{ + Lossless: false, + Quality: float32(t.encOptions.Quality), + } + if err = webp.Encode(w, img, &options); err != nil { + return err + } + } else { + if err = jpeg.Encode(w, img, t.encOptions); err != nil { + return err + } } return nil } diff --git a/transcoder/png.go b/transcoder/png.go index fae0e83..407ef50 100644 --- a/transcoder/png.go +++ b/transcoder/png.go @@ -2,6 +2,7 @@ package transcoder import ( "github.com/barnacs/compy/proxy" + "github.com/chai2010/webp" "image/png" "net/http" ) @@ -13,8 +14,18 @@ func (t *Png) Transcode(w *proxy.ResponseWriter, r *proxy.ResponseReader, header if err != nil { return err } - if err = png.Encode(w, img); err != nil { - return err + + if SupportsWebP(headers) { + options := webp.Options{ + Lossless: true, + } + if err = webp.Encode(w, img, &options); err != nil { + return err + } + } else { + if err = png.Encode(w, img); err != nil { + return err + } } return nil } diff --git a/transcoder/util.go b/transcoder/util.go new file mode 100644 index 0000000..f8711ea --- /dev/null +++ b/transcoder/util.go @@ -0,0 +1,15 @@ +package transcoder + +import ( + "net/http" + "strings" +) + +func SupportsWebP(headers http.Header) bool { + for _, v := range strings.Split(headers.Get("Accept"), ",") { + if strings.SplitN(v, ";", 2)[0] == "image/webp" { + return true + } + } + return false +}