Simplify thumbnail resizing logic to ensure target constraints are respected (#28012)
Automatic Merge
@@ -396,7 +396,7 @@ func TestGenerateThumbnailImage(t *testing.T) {
|
||||
// then
|
||||
outputImage, err := os.Stat(thumbnailPath)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(957), outputImage.Size())
|
||||
assert.Equal(t, int64(721), outputImage.Size())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -26,32 +26,15 @@ func GeneratePreview(img image.Image, width int) image.Image {
|
||||
|
||||
// GenerateThumbnail generates the thumbnail for the given image.
|
||||
func GenerateThumbnail(img image.Image, targetWidth, targetHeight int) image.Image {
|
||||
thumb := img
|
||||
width := img.Bounds().Dx()
|
||||
height := img.Bounds().Dy()
|
||||
expectedRatio := float64(targetHeight) / float64(targetWidth)
|
||||
|
||||
// If both dimensions are over the target size, we scale down until one is not.
|
||||
// If one dimension is over the target size, we scale down until both are not.
|
||||
// If neither dimension is over the target size, we return the image as is.
|
||||
if height > targetHeight || width > targetWidth {
|
||||
ratio := float64(height) / float64(width)
|
||||
if ratio < expectedRatio {
|
||||
if height >= targetHeight {
|
||||
thumb = imaging.Resize(img, 0, targetHeight, imaging.Lanczos)
|
||||
} else {
|
||||
thumb = imaging.Resize(img, targetWidth, 0, imaging.Lanczos)
|
||||
}
|
||||
} else {
|
||||
if width >= targetWidth {
|
||||
thumb = imaging.Resize(img, targetWidth, 0, imaging.Lanczos)
|
||||
} else {
|
||||
thumb = imaging.Resize(img, 0, targetHeight, imaging.Lanczos)
|
||||
}
|
||||
}
|
||||
// We keep aspect ratio and ensure the output dimensions are never higher than the provided targets.
|
||||
if width > height {
|
||||
return imaging.Resize(img, targetWidth, 0, imaging.Lanczos)
|
||||
}
|
||||
|
||||
return thumb
|
||||
return imaging.Resize(img, 0, targetHeight, imaging.Lanczos)
|
||||
}
|
||||
|
||||
// GenerateMiniPreviewImage generates the mini preview for the given image.
|
||||
|
||||
77
server/channels/app/imaging/preview_test.go
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package imaging
|
||||
|
||||
import (
|
||||
"image"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGenerateThumbnail(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
inputImg image.Image
|
||||
targetWidth int
|
||||
targetHeight int
|
||||
expectedWidth int
|
||||
expectedHeight int
|
||||
}{
|
||||
{
|
||||
name: "empty image",
|
||||
inputImg: image.NewRGBA(image.Rect(0, 0, 0, 0)),
|
||||
targetWidth: 120,
|
||||
targetHeight: 100,
|
||||
},
|
||||
{
|
||||
name: "both dimensions lower than targets",
|
||||
inputImg: image.NewRGBA(image.Rect(0, 0, 100, 50)),
|
||||
targetWidth: 120,
|
||||
targetHeight: 100,
|
||||
expectedWidth: 120,
|
||||
expectedHeight: 60,
|
||||
},
|
||||
{
|
||||
name: "both dimensions equal to targets",
|
||||
inputImg: image.NewRGBA(image.Rect(0, 0, 120, 100)),
|
||||
targetWidth: 120,
|
||||
targetHeight: 100,
|
||||
expectedWidth: 120,
|
||||
expectedHeight: 100,
|
||||
},
|
||||
{
|
||||
name: "both dimensions higher than targets",
|
||||
inputImg: image.NewRGBA(image.Rect(0, 0, 1000, 500)),
|
||||
targetWidth: 120,
|
||||
targetHeight: 100,
|
||||
expectedWidth: 120,
|
||||
expectedHeight: 60,
|
||||
},
|
||||
{
|
||||
name: "width higher than target",
|
||||
inputImg: image.NewRGBA(image.Rect(0, 0, 200, 100)),
|
||||
targetWidth: 120,
|
||||
targetHeight: 100,
|
||||
expectedWidth: 120,
|
||||
expectedHeight: 60,
|
||||
},
|
||||
{
|
||||
name: "height higher than target",
|
||||
inputImg: image.NewRGBA(image.Rect(0, 0, 100, 200)),
|
||||
targetWidth: 120,
|
||||
targetHeight: 100,
|
||||
expectedWidth: 50,
|
||||
expectedHeight: 100,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
thumb := GenerateThumbnail(tc.inputImg, tc.targetWidth, tc.targetHeight)
|
||||
require.Equal(t, tc.expectedWidth, thumb.Bounds().Dx(), "expectedWidth")
|
||||
require.Equal(t, tc.expectedHeight, thumb.Bounds().Dy(), "expectedHeight")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.0 KiB |