diff --git a/images/encode.go b/images/encode.go index f0e4a848a..6d6539e49 100644 --- a/images/encode.go +++ b/images/encode.go @@ -24,8 +24,7 @@ func renderJpeg(w io.Writer, m image.Image, config EncodeConfig) error { return jpeg.Encode(w, m, o) } -func EncodeToBestSize(bb *bytes.Buffer, img image.Image, size uint) error { - // TODO test +func EncodeToBestSize(bb *bytes.Buffer, img image.Image, size ResizeDimension) error { q := MaxJpegQuality for q > MinJpegQuality-1 { @@ -50,6 +49,7 @@ func EncodeToBestSize(bb *bytes.Buffer, img image.Image, size uint) error { } } + bb.Reset() q -= 2 } diff --git a/images/encode_test.go b/images/encode_test.go index df2c094fa..8be7c17b9 100644 --- a/images/encode_test.go +++ b/images/encode_test.go @@ -2,6 +2,7 @@ package images import ( "bytes" + "errors" "testing" "github.com/stretchr/testify/require" @@ -44,3 +45,48 @@ func TestEncode(t *testing.T) { require.Exactly(t, c.RenderSize, bb.Len()) } } + +func TestEncodeToBestSize(t *testing.T) { + cs := []struct { + FileName string + RenderSize int + Error error + }{ + { + "elephant.jpg", + 1467, + nil, + }, + { + "rose.webp", + 8513, + errors.New("image size after processing exceeds max, expect < '5632', received < '8513'"), + }, + { + "spin.gif", + 2407, + nil, + }, + { + "status.png", + 4725, + nil, + }, + } + + for _, c := range cs { + img, err := Decode(path + c.FileName) + require.NoError(t, err) + + bb := bytes.NewBuffer([]byte{}) + err = EncodeToBestSize(bb, img, ResizeDimensions[0]) + + require.Exactly(t, c.RenderSize, bb.Len()) + + if c.Error != nil { + require.EqualError(t, err, c.Error.Error()) + } else { + require.NoError(t, err) + } + } +} diff --git a/images/manipulation.go b/images/manipulation.go index 2f080f524..fa34a32c8 100644 --- a/images/manipulation.go +++ b/images/manipulation.go @@ -8,16 +8,16 @@ import ( "github.com/oliamb/cutter" ) -func Resize(size uint, img image.Image) image.Image { +func Resize(size ResizeDimension, img image.Image) image.Image { var width, height uint switch{ case img.Bounds().Max.X == img.Bounds().Max.Y: - width, height = size, size + width, height = uint(size), uint(size) case img.Bounds().Max.X > img.Bounds().Max.Y: - width, height = 0, size + width, height = 0, uint(size) default: - width, height = size, 0 + width, height = uint(size), 0 } return resize.Resize(width, height, img, resize.Bilinear) diff --git a/images/manipulation_test.go b/images/manipulation_test.go index 90878d016..9827de203 100644 --- a/images/manipulation_test.go +++ b/images/manipulation_test.go @@ -10,15 +10,15 @@ import ( ) func TestResize(t *testing.T) { - sizes := []uint{80, 240, 1000} + sizes := []ResizeDimension{80, 240, 1000} cs := []struct{ Filename string - Bounds map[uint]image.Rectangle + Bounds map[ResizeDimension]image.Rectangle }{ { "elephant.jpg", - map[uint]image.Rectangle{ + map[ResizeDimension]image.Rectangle{ 80: { Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 80, Y: 80}, @@ -35,7 +35,7 @@ func TestResize(t *testing.T) { }, { "rose.webp", - map[uint]image.Rectangle{ + map[ResizeDimension]image.Rectangle{ 80: { Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 107, Y: 80}, @@ -52,7 +52,7 @@ func TestResize(t *testing.T) { }, { "spin.gif", - map[uint]image.Rectangle{ + map[ResizeDimension]image.Rectangle{ 80: { Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 80, Y: 80}, @@ -69,7 +69,7 @@ func TestResize(t *testing.T) { }, { "status.png", - map[uint]image.Rectangle{ + map[ResizeDimension]image.Rectangle{ 80: { Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 80, Y: 80}, diff --git a/images/meta.go b/images/meta.go index 6d83f345f..9764ad073 100644 --- a/images/meta.go +++ b/images/meta.go @@ -16,11 +16,11 @@ const ( ) var ( - ResizeDimensions = []uint{80, 240} + ResizeDimensions = []ResizeDimension{80, 240} // DimensionSizeLimit the size limits imposed on each resize dimension // Figures are based on the following sample data https://github.com/status-im/status-react/issues/11047#issuecomment-694970473 - DimensionSizeLimit = map[uint]DimensionSize{ + DimensionSizeLimit = map[ResizeDimension]DimensionLimits{ 80: { Ideal: 2560, // Base on the largest sample image at quality 60% (2,554 bytes ∴ 1024 * 2.5) Max: 5632, // Base on the largest sample image at quality 80% + 50% margin (3,683 bytes * 1.5 ≈ 5500 ∴ 1024 * 5.5) @@ -32,9 +32,10 @@ var ( } ) -type DimensionSize struct { +type DimensionLimits struct { Ideal int Max int } type FileType uint +type ResizeDimension uint