diff --git a/internal/thumb/create_test.go b/internal/thumb/create_test.go new file mode 100644 index 000000000..2dbb9681c --- /dev/null +++ b/internal/thumb/create_test.go @@ -0,0 +1,150 @@ +package thumb + +import ( + "os" + "testing" + + "github.com/disintegration/imaging" + "github.com/photoprism/photoprism/pkg/fs" + "github.com/stretchr/testify/assert" +) + +func TestResampleOptions(t *testing.T) { + method, filter, format := ResampleOptions(ResamplePng, ResampleFillCenter, ResampleDefault) + + assert.Equal(t, ResampleFillCenter, method) + assert.Equal(t, imaging.Lanczos.Support, filter.Support) + assert.Equal(t, fs.TypePng, format) +} + +func TestResample(t *testing.T) { + tile50 := Types["tile_50"] + + src := "testdata/example.jpg" + + assert.FileExists(t, src) + + img, err := imaging.Open(src, imaging.AutoOrientation(true)) + + if err != nil { + t.Fatal(err) + } + + bounds := img.Bounds() + + assert.Equal(t, 750, bounds.Max.X) + assert.Equal(t, 500, bounds.Max.Y) + + result := *Resample(&img, tile50.Width, tile50.Height, tile50.Options...) + + boundsNew := result.Bounds() + + assert.Equal(t, 50, boundsNew.Max.X) + assert.Equal(t, 50, boundsNew.Max.Y) +} + +func TestPostfix(t *testing.T) { + tile50 := Types["tile_50"] + + result := Postfix(tile50.Width, tile50.Height, tile50.Options...) + + assert.Equal(t, "50x50_center.jpg", result) +} + +func TestFilename(t *testing.T) { + t.Run("colors", func(t *testing.T) { + colorThumb := Types["colors"] + + result, err := Filename("123456789098765432", "testdata", colorThumb.Width, colorThumb.Height, colorThumb.Options...) + + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, "testdata/1/2/3/123456789098765432_3x3_resize.png", result) + }) + + t.Run("fit_720", func(t *testing.T) { + fit720 := Types["fit_720"] + + result, err := Filename("123456789098765432", "testdata", fit720.Width, fit720.Height, fit720.Options...) + + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, "testdata/1/2/3/123456789098765432_720x720_fit.jpg", result) + }) +} + +func TestFromFile(t *testing.T) { + t.Run("colors", func(t *testing.T) { + colorThumb := Types["colors"] + src := "testdata/example.gif" + dst := "testdata/1/2/3/123456789098765432_3x3_resize.png" + + assert.FileExists(t, src) + + fileName, err := FromFile(src, "123456789098765432", "testdata", colorThumb.Width, colorThumb.Height, colorThumb.Options...) + + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, dst, fileName) + + assert.FileExists(t, dst) + }) + + t.Run("missing file", func(t *testing.T) { + colorThumb := Types["colors"] + src := "testdata/example.xxx" + + assert.NoFileExists(t, src) + + fileName, err := FromFile(src, "193456789098765432", "testdata", colorThumb.Width, colorThumb.Height, colorThumb.Options...) + + assert.Equal(t, "", fileName) + assert.Error(t, err) + }) +} + +func TestCreate(t *testing.T) { + t.Run("tile_500", func(t *testing.T) { + tile500 := Types["tile_500"] + src := "testdata/example.jpg" + dst := "testdata/example.tile_500.jpg" + + assert.FileExists(t, src) + assert.NoFileExists(t, dst) + + img, err := imaging.Open(src, imaging.AutoOrientation(true)) + + if err != nil { + t.Fatal(err) + } + + bounds := img.Bounds() + + assert.Equal(t, 750, bounds.Max.X) + assert.Equal(t, 500, bounds.Max.Y) + + resized, err := Create(&img, dst, tile500.Width, tile500.Height, tile500.Options...) + + if err != nil { + t.Fatal(err) + } + + assert.FileExists(t, dst) + + if err := os.Remove(dst); err != nil { + t.Fatal(err) + } + + imgNew := *resized + boundsNew := imgNew.Bounds() + + assert.Equal(t, 500, boundsNew.Max.X) + assert.Equal(t, 500, boundsNew.Max.Y) + }) +} diff --git a/internal/thumb/jpeg.go b/internal/thumb/jpeg.go index 410f0a506..97fe08e90 100644 --- a/internal/thumb/jpeg.go +++ b/internal/thumb/jpeg.go @@ -6,23 +6,20 @@ import ( "github.com/disintegration/imaging" ) -func Jpeg(srcFilename, jpgFilename string) (result image.Image, err error) { - img, err := imaging.Open(srcFilename, imaging.AutoOrientation(true)) +func Jpeg(srcFilename, jpgFilename string) (img image.Image, err error) { + img, err = imaging.Open(srcFilename, imaging.AutoOrientation(true)) if err != nil { log.Errorf("thumbs: can't open %s", srcFilename) - return result, err + return img, err } - var saveOption imaging.EncodeOption - saveOption = imaging.JPEGQuality(JpegQuality) + saveOption := imaging.JPEGQuality(JpegQuality) - err = imaging.Save(img, jpgFilename, saveOption) - - if err != nil { + if err = imaging.Save(img, jpgFilename, saveOption); err != nil { log.Errorf("thumbs: failed to save %s", jpgFilename) - return result, err + return img, err } - return result, nil + return img, nil } diff --git a/internal/thumb/jpeg_test.go b/internal/thumb/jpeg_test.go new file mode 100644 index 000000000..8d793dde2 --- /dev/null +++ b/internal/thumb/jpeg_test.go @@ -0,0 +1,55 @@ +package thumb + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestJpeg(t *testing.T) { + formats := []string{"bmp", "gif", "png", "tif"} + + for _, ext := range formats { + t.Run(ext, func(t *testing.T) { + src := "testdata/example." + ext + dst := "testdata/example." + ext +".jpg" + + assert.NoFileExists(t, dst) + + img, err := Jpeg(src, dst) + + if err != nil { + t.Fatal(err) + } + + assert.FileExists(t, dst) + + bounds := img.Bounds() + assert.Equal(t, 100, bounds.Max.X) + assert.Equal(t, 67, bounds.Max.Y) + + if err := os.Remove(dst); err != nil { + t.Fatal(err) + } + }) + } + + t.Run("foo", func(t *testing.T) { + + src := "testdata/example.foo" + dst := "testdata/example.foo.jpg" + + assert.NoFileExists(t, dst) + + img, err := Jpeg(src, dst) + + assert.NoFileExists(t, dst) + + if img != nil { + t.Fatal("img should be nil") + } + + assert.Error(t, err) + }) +} diff --git a/internal/thumb/testdata/example.bmp b/internal/thumb/testdata/example.bmp new file mode 100644 index 000000000..d404d42b2 Binary files /dev/null and b/internal/thumb/testdata/example.bmp differ diff --git a/internal/thumb/testdata/example.gif b/internal/thumb/testdata/example.gif new file mode 100644 index 000000000..d5326632e Binary files /dev/null and b/internal/thumb/testdata/example.gif differ diff --git a/internal/thumb/testdata/example.jpg b/internal/thumb/testdata/example.jpg new file mode 100644 index 000000000..9ae4cfb60 Binary files /dev/null and b/internal/thumb/testdata/example.jpg differ diff --git a/internal/thumb/testdata/example.png b/internal/thumb/testdata/example.png new file mode 100644 index 000000000..77f4ce7cc Binary files /dev/null and b/internal/thumb/testdata/example.png differ diff --git a/internal/thumb/testdata/example.tif b/internal/thumb/testdata/example.tif new file mode 100644 index 000000000..d17692869 Binary files /dev/null and b/internal/thumb/testdata/example.tif differ diff --git a/internal/thumb/thumb_test.go b/internal/thumb/thumb_test.go new file mode 100644 index 000000000..4c46098e1 --- /dev/null +++ b/internal/thumb/thumb_test.go @@ -0,0 +1,24 @@ +package thumb + +import ( + "bytes" + "os" + "testing" + + "github.com/sirupsen/logrus" +) + +var logBuffer bytes.Buffer + +func TestMain(m *testing.M) { + log = logrus.StandardLogger() + log.Out = &logBuffer + log.SetLevel(logrus.DebugLevel) + + code := m.Run() + + // remove temporary test files + os.RemoveAll("testdata/1") + + os.Exit(code) +} diff --git a/internal/thumb/types_test.go b/internal/thumb/types_test.go new file mode 100644 index 000000000..34874baa6 --- /dev/null +++ b/internal/thumb/types_test.go @@ -0,0 +1,41 @@ +package thumb + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestType_ExceedsLimit(t *testing.T) { + PreRenderSize = 1024 + MaxRenderSize = 2048 + + fit3840 := Types["fit_3840"] + assert.True(t, fit3840.ExceedsLimit()) + + fit2048 := Types["fit_2048"] + assert.False(t, fit2048.ExceedsLimit()) + + tile500 := Types["tile_500"] + assert.False(t, tile500.ExceedsLimit()) + + PreRenderSize = 3840 + MaxRenderSize = 3840 +} + +func TestType_SkipPreRender(t *testing.T) { + PreRenderSize = 1024 + MaxRenderSize = 2048 + + fit3840 := Types["fit_3840"] + assert.True(t, fit3840.SkipPreRender()) + + fit2048 := Types["fit_2048"] + assert.True(t, fit2048.SkipPreRender()) + + tile500 := Types["tile_500"] + assert.False(t, tile500.SkipPreRender()) + + PreRenderSize = 3840 + MaxRenderSize = 3840 +}