diff --git a/api/utils.go b/api/utils.go new file mode 100644 index 0000000000000000000000000000000000000000..18c1ccdb397bda6d80c7d0235d25eed016647e8d --- /dev/null +++ b/api/utils.go @@ -0,0 +1,76 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright © 2020 xx network SEZC // +// // +// Use of this source code is governed by a license that can be found in the // +// LICENSE file // +/////////////////////////////////////////////////////////////////////////////// + +// Provides various utility functions for access over the bindings + +package api + +import ( + "bytes" + "github.com/nfnt/resize" + "github.com/pkg/errors" + "image/jpeg" + "math" +) + +const ( + // Maximum input image size (in bytes) + maxSize int64 = 12000000 + // Desired number of pixels in output image + desiredSize = 307200 +) + +// CompressJpeg takes a JPEG image in byte format +// and compresses it based on the above consts +func CompressJpeg(imgBytes []byte) ([]byte, error) { + // Convert bytes to a reader + imgBuf := bytes.NewReader(imgBytes) + + // Ensure the size of the image is under the limit + if imgSize := imgBuf.Size(); imgSize > maxSize { + return nil, errors.Errorf("Image is too large: %d/%d", imgSize, maxSize) + } + + // Decode the image information + imgInfo, err := jpeg.DecodeConfig(imgBuf) + if err != nil { + return nil, errors.Errorf("Unable to decode image config: %+v", err) + } + + // If the dimensions of the image are below desiredSize, no compression is required + if imgInfo.Width*imgInfo.Height < desiredSize { + return imgBytes, nil + } + + // Reset the buffer to the beginning to begin decoding the image + _, err = imgBuf.Seek(0, 0) + if err != nil { + return nil, errors.Errorf("Unable to reset image buffer: %+v", err) + } + + // Decode image into image.Image object + img, err := jpeg.Decode(imgBuf) + if err != nil { + return nil, errors.Errorf("Unable to decode image: %+v", err) + } + + // Determine the new width of the image based on desiredSize + newWidth := uint(math.Sqrt(float64(desiredSize * (imgInfo.Width / imgInfo.Height)))) + + // Resize the image based on newWidth while preserving aspect ratio + newImg := resize.Resize(newWidth, 0, img, resize.Bicubic) + + // Encode the new image to a buffer + var newImgBuf *bytes.Buffer + err = jpeg.Encode(newImgBuf, newImg, nil) + if err != nil { + return nil, errors.Errorf("Unable to encode image: %+v", err) + } + + // Return the compressed image in byte form + return newImgBuf.Bytes(), nil +} diff --git a/go.mod b/go.mod index da05d59a1df31c333810cc34edf813c7cea1ddb0..5fdf6886398abebda1dc3ebb5008e7ce96a1d863 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect github.com/magiconair/properties v1.8.4 // indirect github.com/mitchellh/mapstructure v1.4.0 // indirect + github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/pelletier/go-toml v1.8.1 // indirect github.com/pkg/errors v0.9.1 github.com/smartystreets/assertions v1.0.1 // indirect diff --git a/go.sum b/go.sum index fdd31f7672638b7e93ee8ae057f427b0100711e2..fba3cc4eaafe453c4954475b0c0a3718c6930e85 100644 --- a/go.sum +++ b/go.sum @@ -167,6 +167,8 @@ github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=