Simplify thumbnail resizing logic to ensure target constraints are respected (#28012)
Automatic Merge
@@ -396,7 +396,7 @@ func TestGenerateThumbnailImage(t *testing.T) {
|
|||||||
// then
|
// then
|
||||||
outputImage, err := os.Stat(thumbnailPath)
|
outputImage, err := os.Stat(thumbnailPath)
|
||||||
assert.NoError(t, err)
|
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.
|
// GenerateThumbnail generates the thumbnail for the given image.
|
||||||
func GenerateThumbnail(img image.Image, targetWidth, targetHeight int) image.Image {
|
func GenerateThumbnail(img image.Image, targetWidth, targetHeight int) image.Image {
|
||||||
thumb := img
|
|
||||||
width := img.Bounds().Dx()
|
width := img.Bounds().Dx()
|
||||||
height := img.Bounds().Dy()
|
height := img.Bounds().Dy()
|
||||||
expectedRatio := float64(targetHeight) / float64(targetWidth)
|
|
||||||
|
|
||||||
// If both dimensions are over the target size, we scale down until one is not.
|
// We keep aspect ratio and ensure the output dimensions are never higher than the provided targets.
|
||||||
// If one dimension is over the target size, we scale down until both are not.
|
if width > height {
|
||||||
// If neither dimension is over the target size, we return the image as is.
|
return imaging.Resize(img, targetWidth, 0, imaging.Lanczos)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return thumb
|
return imaging.Resize(img, 0, targetHeight, imaging.Lanczos)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateMiniPreviewImage generates the mini preview for the given image.
|
// GenerateMiniPreviewImage generates the mini preview for the given image.
|
||||||
|
|||||||
77
server/channels/app/imaging/preview_test.go
Обычный файл
@@ -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")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Двоичные данные
server/tests/orientation_test_1_expected_thumb.jpeg
|
До Ширина: | Высота: | Размер: 7.8 KiB После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
server/tests/orientation_test_2_expected_thumb.jpeg
|
До Ширина: | Высота: | Размер: 7.8 KiB После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
server/tests/orientation_test_3_expected_thumb.jpeg
|
До Ширина: | Высота: | Размер: 7.8 KiB После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
server/tests/orientation_test_4_expected_thumb.jpeg
|
До Ширина: | Высота: | Размер: 7.8 KiB После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
server/tests/orientation_test_5_expected_thumb.jpeg
|
До Ширина: | Высота: | Размер: 7.8 KiB После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
server/tests/orientation_test_6_expected_thumb.jpeg
|
До Ширина: | Высота: | Размер: 7.8 KiB После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
server/tests/orientation_test_7_expected_thumb.jpeg
|
До Ширина: | Высота: | Размер: 7.8 KiB После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
server/tests/orientation_test_8_expected_thumb.jpeg
|
До Ширина: | Высота: | Размер: 7.8 KiB После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
server/tests/test_expected_tiff_thumb.jpeg
|
До Ширина: | Высота: | Размер: 3.5 KiB После Ширина: | Высота: | Размер: 3.0 KiB |