People: Refactor thumb package and variable names #22

This commit is contained in:
Michael Mayer 2021-09-05 12:32:08 +02:00
parent 6f5e839e2f
commit d21dc3457c
25 changed files with 153 additions and 176 deletions

View file

@ -57,7 +57,7 @@ func RemoveFromFolderCache(rootName string) {
func RemoveFromAlbumCoverCache(uid string) {
cache := service.CoverCache()
for typeName := range thumb.Types {
for typeName := range thumb.Sizes {
cacheKey := CacheKey(albumCover, uid, typeName)
cache.Delete(cacheKey)

View file

@ -38,7 +38,7 @@ func AlbumCover(router *gin.RouterGroup) {
typeName := c.Param("type")
uid := c.Param("uid")
thumbType, ok := thumb.Types[typeName]
size, ok := thumb.Sizes[typeName]
if !ok {
log.Errorf("%s: invalid type %s", albumCover, typeName)
@ -92,8 +92,8 @@ func AlbumCover(router *gin.RouterGroup) {
}
// Use original file if thumb size exceeds limit, see https://github.com/photoprism/photoprism/issues/157
if thumbType.ExceedsSizeUncached() && c.Query("download") == "" {
log.Debugf("%s: using original, size exceeds limit (width %d, height %d)", albumCover, thumbType.Width, thumbType.Height)
if size.ExceedsLimit() && c.Query("download") == "" {
log.Debugf("%s: using original, size exceeds limit (width %d, height %d)", albumCover, size.Width, size.Height)
AddCoverCacheHeader(c)
c.File(fileName)
return
@ -101,10 +101,10 @@ func AlbumCover(router *gin.RouterGroup) {
var thumbnail string
if conf.ThumbUncached() || thumbType.OnDemand() {
thumbnail, err = thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, f.FileOrientation, thumbType.Options...)
if conf.ThumbUncached() || size.Uncached() {
thumbnail, err = thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), size.Width, size.Height, f.FileOrientation, size.Options...)
} else {
thumbnail, err = thumb.FromCache(fileName, f.FileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, thumbType.Options...)
thumbnail, err = thumb.FromCache(fileName, f.FileHash, conf.ThumbPath(), size.Width, size.Height, size.Options...)
}
if err != nil {
@ -148,7 +148,7 @@ func LabelCover(router *gin.RouterGroup) {
typeName := c.Param("type")
uid := c.Param("uid")
thumbType, ok := thumb.Types[typeName]
size, ok := thumb.Sizes[typeName]
if !ok {
log.Errorf("%s: invalid type %s", labelCover, txt.Quote(typeName))
@ -202,8 +202,8 @@ func LabelCover(router *gin.RouterGroup) {
}
// Use original file if thumb size exceeds limit, see https://github.com/photoprism/photoprism/issues/157
if thumbType.ExceedsSizeUncached() {
log.Debugf("%s: using original, size exceeds limit (width %d, height %d)", labelCover, thumbType.Width, thumbType.Height)
if size.ExceedsLimit() {
log.Debugf("%s: using original, size exceeds limit (width %d, height %d)", labelCover, size.Width, size.Height)
AddCoverCacheHeader(c)
c.File(fileName)
@ -213,10 +213,10 @@ func LabelCover(router *gin.RouterGroup) {
var thumbnail string
if conf.ThumbUncached() || thumbType.OnDemand() {
thumbnail, err = thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, f.FileOrientation, thumbType.Options...)
if conf.ThumbUncached() || size.Uncached() {
thumbnail, err = thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), size.Width, size.Height, f.FileOrientation, size.Options...)
} else {
thumbnail, err = thumb.FromCache(fileName, f.FileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, thumbType.Options...)
thumbnail, err = thumb.FromCache(fileName, f.FileHash, conf.ThumbPath(), size.Width, size.Height, size.Options...)
}
if err != nil {

View file

@ -23,7 +23,7 @@ const (
// Parameters:
// uid: string folder uid
// token: string url security token, see config
// type: string thumb type, see thumb.Types
// type: string thumb type, see thumb.Sizes
func GetFolderCover(router *gin.RouterGroup) {
router.GET("/folders/t/:uid/:token/:type", func(c *gin.Context) {
if InvalidPreviewToken(c) {
@ -37,7 +37,7 @@ func GetFolderCover(router *gin.RouterGroup) {
typeName := c.Param("type")
download := c.Query("download") != ""
thumbType, ok := thumb.Types[typeName]
size, ok := thumb.Sizes[typeName]
if !ok {
log.Errorf("folder: invalid thumb type %s", txt.Quote(typeName))
@ -45,11 +45,11 @@ func GetFolderCover(router *gin.RouterGroup) {
return
}
if thumbType.ExceedsSize() && !conf.ThumbUncached() {
typeName, thumbType = thumb.Find(conf.ThumbSize())
if size.Uncached() && !conf.ThumbUncached() {
typeName, size = thumb.Find(conf.ThumbSizePrecached())
if typeName == "" {
log.Errorf("folder: invalid thumb size %d", conf.ThumbSize())
log.Errorf("folder: invalid thumb size %d", conf.ThumbSizePrecached())
c.Data(http.StatusOK, "image/svg+xml", folderIconSvg)
return
}
@ -101,8 +101,8 @@ func GetFolderCover(router *gin.RouterGroup) {
}
// Use original file if thumb size exceeds limit, see https://github.com/photoprism/photoprism/issues/157
if thumbType.ExceedsSizeUncached() && !download {
log.Debugf("%s: using original, size exceeds limit (width %d, height %d)", folderCover, thumbType.Width, thumbType.Height)
if size.ExceedsLimit() && !download {
log.Debugf("%s: using original, size exceeds limit (width %d, height %d)", folderCover, size.Width, size.Height)
AddCoverCacheHeader(c)
c.File(fileName)
return
@ -110,10 +110,10 @@ func GetFolderCover(router *gin.RouterGroup) {
var thumbnail string
if conf.ThumbUncached() || thumbType.OnDemand() {
thumbnail, err = thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, f.FileOrientation, thumbType.Options...)
if conf.ThumbUncached() || size.Uncached() {
thumbnail, err = thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), size.Width, size.Height, f.FileOrientation, size.Options...)
} else {
thumbnail, err = thumb.FromCache(fileName, f.FileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, thumbType.Options...)
thumbnail, err = thumb.FromCache(fileName, f.FileHash, conf.ThumbPath(), size.Width, size.Height, size.Options...)
}
if err != nil {

View file

@ -23,7 +23,7 @@ import (
// Parameters:
// hash: string sha1 file hash
// token: string url security token, see config
// type: string thumb type, see thumb.Types
// type: string thumb type, see thumb.Sizes
func GetThumb(router *gin.RouterGroup) {
router.GET("/t/:hash/:token/:type", func(c *gin.Context) {
if InvalidPreviewToken(c) {
@ -37,7 +37,7 @@ func GetThumb(router *gin.RouterGroup) {
typeName := c.Param("type")
download := c.Query("download") != ""
thumbType, ok := thumb.Types[typeName]
size, ok := thumb.Sizes[typeName]
if !ok {
log.Errorf("thumbs: invalid type %s", txt.Quote(typeName))
@ -45,11 +45,11 @@ func GetThumb(router *gin.RouterGroup) {
return
}
if thumbType.ExceedsSize() && !conf.ThumbUncached() {
typeName, thumbType = thumb.Find(conf.ThumbSize())
if size.Uncached() && !conf.ThumbUncached() {
typeName, size = thumb.Find(conf.ThumbSizePrecached())
if typeName == "" {
log.Errorf("thumbs: invalid size %d", conf.ThumbSize())
log.Errorf("thumbs: invalid size %d", conf.ThumbSizePrecached())
c.Data(http.StatusOK, "image/svg+xml", photoIconSvg)
return
}
@ -82,7 +82,7 @@ func GetThumb(router *gin.RouterGroup) {
// Return existing thumbs straight away.
if !download {
if fileName, err := thumb.FileName(fileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, thumbType.Options...); err == nil && fs.FileExists(fileName) {
if fileName, err := thumb.FileName(fileHash, conf.ThumbPath(), size.Width, size.Height, size.Options...); err == nil && fs.FileExists(fileName) {
c.File(fileName)
return
}
@ -131,8 +131,8 @@ func GetThumb(router *gin.RouterGroup) {
}
// Use original file if thumb size exceeds limit, see https://github.com/photoprism/photoprism/issues/157
if thumbType.ExceedsSizeUncached() && c.Query("download") == "" {
log.Debugf("thumbs: using original, size exceeds limit (width %d, height %d)", thumbType.Width, thumbType.Height)
if size.ExceedsLimit() && c.Query("download") == "" {
log.Debugf("thumbs: using original, size exceeds limit (width %d, height %d)", size.Width, size.Height)
AddThumbCacheHeader(c)
c.File(fileName)
@ -142,10 +142,10 @@ func GetThumb(router *gin.RouterGroup) {
var thumbnail string
if conf.ThumbUncached() || thumbType.OnDemand() {
thumbnail, err = thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, f.FileOrientation, thumbType.Options...)
if conf.ThumbUncached() || size.Uncached() {
thumbnail, err = thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), size.Width, size.Height, f.FileOrientation, size.Options...)
} else {
thumbnail, err = thumb.FromCache(fileName, f.FileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, thumbType.Options...)
thumbnail, err = thumb.FromCache(fileName, f.FileHash, conf.ThumbPath(), size.Width, size.Height, size.Options...)
}
if err != nil {
@ -178,7 +178,7 @@ func GetThumb(router *gin.RouterGroup) {
// Parameters:
// hash: string sha1 file hash
// token: string url security token, see config
// type: string thumb type, see thumb.Types
// type: string thumb type, see thumb.Sizes
// area: string image area identifier, e.g. 022004010015
func GetThumbCrop(router *gin.RouterGroup) {
router.GET("/t/:hash/:token/:type/:area", func(c *gin.Context) {
@ -193,19 +193,19 @@ func GetThumbCrop(router *gin.RouterGroup) {
cropArea := c.Param("area")
download := c.Query("download") != ""
thumbType, ok := thumb.Types[typeName]
size, ok := thumb.Sizes[typeName]
if !ok || len(thumbType.Options) < 1 {
if !ok || len(size.Options) < 1 {
log.Errorf("thumbs: invalid type %s", txt.Quote(typeName))
c.Data(http.StatusOK, "image/svg+xml", photoIconSvg)
return
} else if thumbType.Options[0] != thumb.ResampleCrop {
} else if size.Options[0] != thumb.ResampleCrop {
log.Errorf("thumbs: invalid crop %s", txt.Quote(typeName))
c.Data(http.StatusOK, "image/svg+xml", photoIconSvg)
return
}
fileName, err := crop.FromCache(fileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, cropArea)
fileName, err := crop.FromCache(fileHash, conf.ThumbPath(), size.Width, size.Height, cropArea)
if err != nil {
log.Errorf("thumbs: %s", err)

View file

@ -88,7 +88,7 @@ func SharePreview(router *gin.RouterGroup) {
return
} else if count < 12 {
f := p[0]
thumbType, _ := thumb.Types["fit_720"]
size, _ := thumb.Sizes["fit_720"]
fileName := photoprism.FileName(f.FileRoot, f.FileName)
@ -98,7 +98,7 @@ func SharePreview(router *gin.RouterGroup) {
return
}
thumbnail, err := thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, f.FileOrientation, thumbType.Options...)
thumbnail, err := thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), size.Width, size.Height, f.FileOrientation, size.Options...)
if err != nil {
log.Error(err)
@ -117,7 +117,7 @@ func SharePreview(router *gin.RouterGroup) {
y := 0
preview := imaging.New(width, height, color.NRGBA{255, 255, 255, 255})
thumbType, _ := thumb.Types["tile_224"]
size, _ := thumb.Sizes["tile_224"]
for _, f := range p {
fileName := photoprism.FileName(f.FileRoot, f.FileName)
@ -128,7 +128,7 @@ func SharePreview(router *gin.RouterGroup) {
return
}
thumbnail, err := thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), thumbType.Width, thumbType.Height, f.FileOrientation, thumbType.Options...)
thumbnail, err := thumb.FromFile(fileName, f.FileHash, conf.ThumbPath(), size.Width, size.Height, f.FileOrientation, size.Options...)
if err != nil {
log.Error(err)

View file

@ -132,7 +132,7 @@ func configAction(ctx *cli.Context) error {
fmt.Printf("%-25s %s\n", "preview-token", conf.PreviewToken())
fmt.Printf("%-25s %s\n", "thumb-filter", conf.ThumbFilter())
fmt.Printf("%-25s %t\n", "thumb-uncached", conf.ThumbUncached())
fmt.Printf("%-25s %d\n", "thumb-size", conf.ThumbSize())
fmt.Printf("%-25s %d\n", "thumb-size", conf.ThumbSizePrecached())
fmt.Printf("%-25s %d\n", "thumb-size-uncached", conf.ThumbSizeUncached())
fmt.Printf("%-25s %s\n", "thumb-path", conf.ThumbPath())
fmt.Printf("%-25s %d\n", "jpeg-size", conf.JpegSize())

View file

@ -9,21 +9,21 @@ import (
"github.com/urfave/cli"
)
// ResampleCommand registers the thumbs cli command.
// ResampleCommand registers the resample cli command.
var ResampleCommand = cli.Command{
Name: "resample",
Aliases: []string{"thumbs"},
Usage: "Pre-renders thumbnails (significantly reduces memory and cpu usage)",
Usage: "Pre-caches thumbnails to reduce memory and cpu usage",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "re-create existing thumbnails",
Usage: "replace existing thumbnails",
},
},
Action: resampleAction,
}
// resampleAction pre-render the thumbnails
// resampleAction pre-caches default thumbnails.
func resampleAction(ctx *cli.Context) error {
start := time.Now()

View file

@ -43,7 +43,7 @@ type ClientConfig struct {
Lenses entity.Lenses `json:"lenses"`
Countries entity.Countries `json:"countries"`
People entity.People `json:"people"`
Thumbs ThumbTypes `json:"thumbs"`
Thumbs ThumbSizes `json:"thumbs"`
Status string `json:"status"`
MapKey string `json:"mapKey"`
DownloadToken string `json:"downloadToken"`

View file

@ -72,12 +72,12 @@ func init() {
LowMem = TotalMem < MinMem
// Init public thumb sizes for use in client apps.
for i := len(thumb.DefaultTypes) - 1; i >= 0; i-- {
size := thumb.DefaultTypes[i]
t := thumb.Types[size]
for i := len(thumb.DefaultSizes) - 1; i >= 0; i-- {
name := thumb.DefaultSizes[i]
t := thumb.Sizes[name]
if t.Public {
Thumbs = append(Thumbs, ThumbType{Size: size, Use: t.Use, Width: t.Width, Height: t.Height})
Thumbs = append(Thumbs, ThumbSize{Size: name, Use: t.Use, Width: t.Width, Height: t.Height})
}
}
}
@ -131,7 +131,7 @@ func (c *Config) Options() *Options {
func (c *Config) Propagate() {
log.SetLevel(c.LogLevel())
thumb.Size = c.ThumbSize()
thumb.SizePrecached = c.ThumbSizePrecached()
thumb.SizeUncached = c.ThumbSizeUncached()
thumb.Filter = c.ThumbFilter()
thumb.JpegQuality = c.JpegQuality()

View file

@ -5,7 +5,7 @@ import (
"github.com/urfave/cli"
)
// PhotoPrism command-line parameters and flags.
// GlobalFlags describes global command-line parameters and flags.
var GlobalFlags = []cli.Flag{
cli.BoolFlag{
Name: "debug",
@ -387,7 +387,7 @@ var GlobalFlags = []cli.Flag{
},
cli.IntFlag{
Name: "thumb-size, s",
Usage: "static thumbnail size limit in `PIXELS` (720-7680)",
Usage: "pre-cached thumbnail size in `PIXELS` (720-7680)",
Value: 2048,
EnvVar: "PHOTOPRISM_THUMB_SIZE",
},

View file

@ -56,8 +56,8 @@ func (c *Config) ThumbUncached() bool {
return c.options.ThumbUncached
}
// ThumbSize returns the pre-rendered thumbnail size limit in pixels (720-7680).
func (c *Config) ThumbSize() int {
// ThumbSizePrecached returns the pre-cached thumbnail size limit in pixels (720-7680).
func (c *Config) ThumbSizePrecached() int {
size := c.options.ThumbSize
if size < 720 {
@ -79,8 +79,8 @@ func (c *Config) ThumbSizeUncached() int {
limit = 7680 // 8K Ultra HD
}
if c.ThumbSize() > limit {
limit = c.ThumbSize()
if c.ThumbSizePrecached() > limit {
limit = c.ThumbSizePrecached()
}
return limit

View file

@ -50,9 +50,9 @@ func TestConfig_ThumbSizeUncached(t *testing.T) {
func TestConfig_ThumbSize(t *testing.T) {
c := NewConfig(CliTestContext())
assert.Equal(t, int(720), c.ThumbSize())
assert.Equal(t, int(720), c.ThumbSizePrecached())
c.options.ThumbSize = 7681
assert.Equal(t, int(7680), c.ThumbSize())
assert.Equal(t, int(7680), c.ThumbSizePrecached())
}
func TestConfig_ThumbSizeUncached2(t *testing.T) {

View file

@ -138,7 +138,7 @@ func NewTestConfig() *Config {
c.InitTestDb()
thumb.Size = c.ThumbSize()
thumb.SizePrecached = c.ThumbSizePrecached()
thumb.SizeUncached = c.ThumbSizeUncached()
thumb.Filter = c.ThumbFilter()
thumb.JpegQuality = c.JpegQuality()

View file

@ -1,15 +1,15 @@
package config
// ThumbType represents thumbnail info for use in client apps.
type ThumbType struct {
// ThumbSize represents thumbnail info for use in client apps.
type ThumbSize struct {
Size string `json:"size"`
Use string `json:"use"`
Width int `json:"w"`
Height int `json:"h"`
}
// ThumbTypes represents a list of thumbnail types.
type ThumbTypes []ThumbType
// ThumbSizes represents a list of thumbnail types.
type ThumbSizes []ThumbSize
// Thumbs is a list of thumbnails for use in client apps.
var Thumbs ThumbTypes
var Thumbs ThumbSizes

View file

@ -210,7 +210,7 @@ func ImportWorker(jobs <-chan ImportJob) {
if res.Indexed() && f.IsJpeg() {
if err := f.ResampleDefault(ind.thumbPath(), false); err != nil {
log.Errorf("import: failed creating thumbnails for %s (%s)", txt.Quote(f.BaseName()), err.Error())
log.Errorf("import: failed creating thumbs for %s (%s)", txt.Quote(f.BaseName()), err.Error())
query.SetFileError(res.FileUID, err.Error())
}
}

View file

@ -17,7 +17,7 @@ func (ind *Index) detectFaces(jpeg *MediaFile) face.Faces {
var thumbSize string
// Select best thumbnail depending on configured size.
if Config().ThumbSize() < 1280 {
if Config().ThumbSizePrecached() < 1280 {
minSize = 30
thumbSize = "fit_720"
} else {

View file

@ -45,7 +45,7 @@ func IndexMain(related *RelatedFiles, ind *Index, opt IndexOptions) (result Inde
log.Debugf("index: %s created", txt.Quote(jpegFile.BaseName()))
if err := jpegFile.ResampleDefault(ind.thumbPath(), false); err != nil {
result.Err = fmt.Errorf("index: failed creating thumbnails for %s (%s)", txt.Quote(f.BaseName()), err.Error())
result.Err = fmt.Errorf("index: failed creating thumbs for %s (%s)", txt.Quote(f.BaseName()), err.Error())
result.Status = IndexFailed
return result
@ -59,7 +59,7 @@ func IndexMain(related *RelatedFiles, ind *Index, opt IndexOptions) (result Inde
if result.Indexed() && f.IsJpeg() {
if err := f.ResampleDefault(ind.thumbPath(), false); err != nil {
log.Errorf("index: failed creating thumbnails for %s (%s)", txt.Quote(f.BaseName()), err.Error())
log.Errorf("index: failed creating thumbs for %s (%s)", txt.Quote(f.BaseName()), err.Error())
query.SetFileError(result.FileUID, err.Error())
}
}
@ -126,7 +126,7 @@ func IndexRelated(related RelatedFiles, ind *Index, opt IndexOptions) (result In
log.Debugf("index: %s created", txt.Quote(jpegFile.BaseName()))
if err := jpegFile.ResampleDefault(ind.thumbPath(), false); err != nil {
result.Err = fmt.Errorf("index: failed creating thumbnails for %s (%s)", txt.Quote(f.BaseName()), err.Error())
result.Err = fmt.Errorf("index: failed creating thumbs for %s (%s)", txt.Quote(f.BaseName()), err.Error())
result.Status = IndexFailed
return result
@ -140,7 +140,7 @@ func IndexRelated(related RelatedFiles, ind *Index, opt IndexOptions) (result In
if res.Indexed() && f.IsJpeg() {
if err := f.ResampleDefault(ind.thumbPath(), false); err != nil {
log.Errorf("index: failed creating thumbnails for %s (%s)", txt.Quote(f.BaseName()), err.Error())
log.Errorf("index: failed creating thumbs for %s (%s)", txt.Quote(f.BaseName()), err.Error())
query.SetFileError(res.FileUID, err.Error())
}
}

View file

@ -888,14 +888,14 @@ func (m *MediaFile) Orientation() int {
// Thumbnail returns a thumbnail filename.
func (m *MediaFile) Thumbnail(path string, typeName string) (filename string, err error) {
thumbType, ok := thumb.Types[typeName]
size, ok := thumb.Sizes[typeName]
if !ok {
log.Errorf("media: invalid type %s", typeName)
return "", fmt.Errorf("media: invalid type %s", typeName)
}
thumbnail, err := thumb.FromFile(m.FileName(), m.Hash(), path, thumbType.Width, thumbType.Height, m.Orientation(), thumbType.Options...)
thumbnail, err := thumb.FromFile(m.FileName(), m.Hash(), path, size.Width, size.Height, m.Orientation(), size.Options...)
if err != nil {
err = fmt.Errorf("media: failed creating thumbnail for %s (%s)", txt.Quote(m.BaseName()), err)
@ -917,7 +917,7 @@ func (m *MediaFile) Resample(path string, typeName string) (img image.Image, err
return imaging.Open(filename)
}
// ResampleDefault pre-renders default thumbnails.
// ResampleDefault pre-caches default thumbnails.
func (m *MediaFile) ResampleDefault(thumbPath string, force bool) (err error) {
count := 0
start := time.Now()
@ -925,11 +925,11 @@ func (m *MediaFile) ResampleDefault(thumbPath string, force bool) (err error) {
defer func() {
switch count {
case 0:
log.Debug(capture.Time(start, fmt.Sprintf("media: no new thumbnails created for %s", m.BasePrefix(false))))
log.Debug(capture.Time(start, fmt.Sprintf("media: no new thumbs created for %s", m.BasePrefix(false))))
case 1:
log.Info(capture.Time(start, fmt.Sprintf("media: one thumbnail created for %s", m.BasePrefix(false))))
default:
log.Info(capture.Time(start, fmt.Sprintf("media: %d thumbnails created for %s", count, m.BasePrefix(false))))
log.Info(capture.Time(start, fmt.Sprintf("media: %d thumbs created for %s", count, m.BasePrefix(false))))
}
}()
@ -939,15 +939,15 @@ func (m *MediaFile) ResampleDefault(thumbPath string, force bool) (err error) {
var sourceImg image.Image
var sourceImgType string
for _, name := range thumb.DefaultTypes {
thumbType := thumb.Types[name]
for _, name := range thumb.DefaultSizes {
size := thumb.Sizes[name]
if thumbType.OnDemand() {
// Skip, size exceeds limit
if size.Uncached() {
// Skip, exceeds pre-cached size limit.
continue
}
if fileName, err := thumb.FileName(hash, thumbPath, thumbType.Width, thumbType.Height, thumbType.Options...); err != nil {
if fileName, err := thumb.FileName(hash, thumbPath, size.Width, size.Height, size.Options...); err != nil {
log.Errorf("media: failed creating %s (%s)", txt.Quote(name), err)
return err
@ -969,14 +969,14 @@ func (m *MediaFile) ResampleDefault(thumbPath string, force bool) (err error) {
originalImg = img
}
if thumbType.Source != "" {
if thumbType.Source == sourceImgType && sourceImg != nil {
_, err = thumb.Create(sourceImg, fileName, thumbType.Width, thumbType.Height, thumbType.Options...)
if size.Source != "" {
if size.Source == sourceImgType && sourceImg != nil {
_, err = thumb.Create(sourceImg, fileName, size.Width, size.Height, size.Options...)
} else {
_, err = thumb.Create(originalImg, fileName, thumbType.Width, thumbType.Height, thumbType.Options...)
_, err = thumb.Create(originalImg, fileName, size.Width, size.Height, size.Options...)
}
} else {
sourceImg, err = thumb.Create(originalImg, fileName, thumbType.Width, thumbType.Height, thumbType.Options...)
sourceImg, err = thumb.Create(originalImg, fileName, size.Width, size.Height, size.Options...)
sourceImgType = name
}

View file

@ -1873,7 +1873,7 @@ func TestMediaFile_RenderDefaultThumbs(t *testing.T) {
t.Fatal(err)
}
thumbFilename, err := thumb.FileName(m.Hash(), thumbsPath, thumb.Types["tile_50"].Width, thumb.Types["tile_50"].Height, thumb.Types["tile_50"].Options...)
thumbFilename, err := thumb.FileName(m.Hash(), thumbsPath, thumb.Sizes["tile_50"].Width, thumb.Sizes["tile_50"].Height, thumb.Sizes["tile_50"].Options...)
if err != nil {
t.Fatal(err)

View file

@ -35,7 +35,7 @@ func TestResampleOptions(t *testing.T) {
func TestResample(t *testing.T) {
t.Run("tile50 options", func(t *testing.T) {
tile50 := Types["tile_50"]
tile50 := Sizes["tile_50"]
src := "testdata/example.jpg"
@ -60,7 +60,7 @@ func TestResample(t *testing.T) {
assert.Equal(t, 50, boundsNew.Max.Y)
})
t.Run("left_224 options", func(t *testing.T) {
left224 := Types["left_224"]
left224 := Sizes["left_224"]
src := "testdata/example.jpg"
@ -85,7 +85,7 @@ func TestResample(t *testing.T) {
assert.Equal(t, 224, boundsNew.Max.Y)
})
t.Run("right_224 options", func(t *testing.T) {
right224 := Types["right_224"]
right224 := Sizes["right_224"]
src := "testdata/example.jpg"
@ -110,7 +110,7 @@ func TestResample(t *testing.T) {
assert.Equal(t, 224, boundsNew.Max.Y)
})
t.Run("fit_1280 options", func(t *testing.T) {
fit1280 := Types["fit_1280"]
fit1280 := Sizes["fit_1280"]
src := "testdata/example.jpg"
@ -137,7 +137,7 @@ func TestResample(t *testing.T) {
}
func TestSuffix(t *testing.T) {
tile50 := Types["tile_50"]
tile50 := Sizes["tile_50"]
result := Suffix(tile50.Width, tile50.Height, tile50.Options...)
@ -146,7 +146,7 @@ func TestSuffix(t *testing.T) {
func TestFileName(t *testing.T) {
t.Run("colors", func(t *testing.T) {
colorThumb := Types["colors"]
colorThumb := Sizes["colors"]
result, err := FileName("123456789098765432", "testdata", colorThumb.Width, colorThumb.Height, colorThumb.Options...)
@ -158,7 +158,7 @@ func TestFileName(t *testing.T) {
})
t.Run("fit_720", func(t *testing.T) {
fit720 := Types["fit_720"]
fit720 := Sizes["fit_720"]
result, err := FileName("123456789098765432", "testdata", fit720.Width, fit720.Height, fit720.Options...)
@ -169,7 +169,7 @@ func TestFileName(t *testing.T) {
assert.Equal(t, "testdata/1/2/3/123456789098765432_720x720_fit.jpg", result)
})
t.Run("invalid width", func(t *testing.T) {
colorThumb := Types["colors"]
colorThumb := Sizes["colors"]
result, err := FileName("123456789098765432", "testdata", -2, colorThumb.Height, colorThumb.Options...)
@ -180,7 +180,7 @@ func TestFileName(t *testing.T) {
assert.Empty(t, result)
})
t.Run("invalid height", func(t *testing.T) {
colorThumb := Types["colors"]
colorThumb := Sizes["colors"]
result, err := FileName("123456789098765432", "testdata", colorThumb.Width, -3, colorThumb.Options...)
@ -191,7 +191,7 @@ func TestFileName(t *testing.T) {
assert.Empty(t, result)
})
t.Run("invalid hash", func(t *testing.T) {
colorThumb := Types["colors"]
colorThumb := Sizes["colors"]
result, err := FileName("12", "testdata", colorThumb.Width, colorThumb.Height, colorThumb.Options...)
@ -202,7 +202,7 @@ func TestFileName(t *testing.T) {
assert.Empty(t, result)
})
t.Run("invalid thumb path", func(t *testing.T) {
colorThumb := Types["colors"]
colorThumb := Sizes["colors"]
result, err := FileName("123456789098765432", "", colorThumb.Width, colorThumb.Height, colorThumb.Options...)
@ -216,7 +216,7 @@ func TestFileName(t *testing.T) {
func TestFromFile(t *testing.T) {
t.Run("colors", func(t *testing.T) {
colorThumb := Types["colors"]
colorThumb := Sizes["colors"]
src := "testdata/example.gif"
dst := "testdata/1/2/3/123456789098765432_3x3_resize.png"
@ -234,7 +234,7 @@ func TestFromFile(t *testing.T) {
})
t.Run("orientation >1 ", func(t *testing.T) {
colorThumb := Types["colors"]
colorThumb := Sizes["colors"]
src := "testdata/example.gif"
dst := "testdata/1/2/3/123456789098765432_3x3_resize.png"
@ -252,7 +252,7 @@ func TestFromFile(t *testing.T) {
})
t.Run("missing file", func(t *testing.T) {
colorThumb := Types["colors"]
colorThumb := Sizes["colors"]
src := "testdata/example.xxx"
assert.NoFileExists(t, src)
@ -263,7 +263,7 @@ func TestFromFile(t *testing.T) {
assert.Error(t, err)
})
t.Run("empty filename", func(t *testing.T) {
colorThumb := Types["colors"]
colorThumb := Sizes["colors"]
fileName, err := FromFile("", "193456789098765432", "testdata", colorThumb.Width, colorThumb.Height, OrientationNormal, colorThumb.Options...)
@ -277,7 +277,7 @@ func TestFromFile(t *testing.T) {
func TestFromCache(t *testing.T) {
t.Run("missing thumb", func(t *testing.T) {
tile50 := Types["tile_50"]
tile50 := Sizes["tile_50"]
src := "testdata/example.jpg"
assert.FileExists(t, src)
@ -292,7 +292,7 @@ func TestFromCache(t *testing.T) {
})
t.Run("missing file", func(t *testing.T) {
tile50 := Types["tile_50"]
tile50 := Sizes["tile_50"]
src := "testdata/example.xxx"
assert.NoFileExists(t, src)
@ -303,7 +303,7 @@ func TestFromCache(t *testing.T) {
assert.Error(t, err)
})
t.Run("invalid hash", func(t *testing.T) {
tile50 := Types["tile_50"]
tile50 := Sizes["tile_50"]
src := "testdata/example.jpg"
assert.FileExists(t, src)
@ -317,7 +317,7 @@ func TestFromCache(t *testing.T) {
assert.Empty(t, fileName)
})
t.Run("empty filename", func(t *testing.T) {
tile50 := Types["tile_50"]
tile50 := Sizes["tile_50"]
fileName, err := FromCache("", "193456789098765432", "testdata", tile50.Width, tile50.Height, tile50.Options...)
@ -331,7 +331,7 @@ func TestFromCache(t *testing.T) {
func TestCreate(t *testing.T) {
t.Run("tile_500", func(t *testing.T) {
tile500 := Types["tile_500"]
tile500 := Sizes["tile_500"]
src := "testdata/example.jpg"
dst := "testdata/example.tile_500.jpg"
@ -368,7 +368,7 @@ func TestCreate(t *testing.T) {
assert.Equal(t, 500, boundsNew.Max.Y)
})
t.Run("width & height <= 150", func(t *testing.T) {
tile500 := Types["tile_500"]
tile500 := Sizes["tile_500"]
src := "testdata/example.jpg"
dst := "testdata/example.tile_500.jpg"
@ -405,7 +405,7 @@ func TestCreate(t *testing.T) {
assert.Equal(t, 150, boundsNew.Max.Y)
})
t.Run("invalid width", func(t *testing.T) {
tile500 := Types["tile_500"]
tile500 := Sizes["tile_500"]
src := "testdata/example.jpg"
dst := "testdata/example.tile_500.jpg"
@ -433,7 +433,7 @@ func TestCreate(t *testing.T) {
t.Log(resized)
})
t.Run("invalid height", func(t *testing.T) {
tile500 := Types["tile_500"]
tile500 := Sizes["tile_500"]
src := "testdata/example.jpg"
dst := "testdata/example.tile_500.jpg"

View file

@ -235,7 +235,6 @@ func TestJpeg(t *testing.T) {
}
t.Run("foo", func(t *testing.T) {
src := "testdata/example.foo"
dst := "testdata/example.foo.jpg"

View file

@ -3,16 +3,16 @@ package thumb
import "github.com/disintegration/imaging"
var (
Size = 2048
SizePrecached = 2048
SizeUncached = 7680
Filter = ResampleLanczos
JpegQuality = 95
JpegQualitySmall = 80
Filter = ResampleLanczos
)
func MaxSize() int {
if Size > SizeUncached {
return Size
if SizePrecached > SizeUncached {
return SizePrecached
}
return SizeUncached
@ -69,7 +69,7 @@ var ResampleMethods = map[ResampleOption]string{
ResampleResize: "resize",
}
type Type struct {
type Size struct {
Use string `json:"use"`
Source string `json:"-"`
Width int `json:"w"`
@ -78,9 +78,9 @@ type Type struct {
Options []ResampleOption `json:"-"`
}
type TypeMap map[string]Type
type SizeMap map[string]Size
var Types = TypeMap{
var Sizes = SizeMap{
"tile_50": {"Lists", "tile_500", 50, 50, false, []ResampleOption{ResampleFillCenter, ResampleDefault}},
"tile_100": {"Maps", "tile_500", 100, 100, false, []ResampleOption{ResampleFillCenter, ResampleDefault}},
"crop_160": {"FaceNet", "", 160, 160, false, []ResampleOption{ResampleCrop, ResampleDefault}},
@ -99,7 +99,7 @@ var Types = TypeMap{
"fit_7680": {"8K Ultra HD 2, Retina 6K", "", 7680, 4320, true, []ResampleOption{ResampleFit, ResampleDefault}},
}
var DefaultTypes = []string{
var DefaultSizes = []string{
"fit_7680",
"fit_4096",
"fit_2560",
@ -117,29 +117,24 @@ var DefaultTypes = []string{
}
// Find returns the largest default thumbnail type for the given size limit.
func Find(limit int) (name string, result Type) {
for _, name = range DefaultTypes {
t := Types[name]
func Find(limit int) (name string, result Size) {
for _, name = range DefaultSizes {
t := Sizes[name]
if t.Width <= limit && t.Height <= limit {
return name, t
}
}
return "", Type{}
return "", Size{}
}
// ExceedsSize tests if thumbnail type exceeds the cached thumbnails size.
func (t Type) ExceedsSize() bool {
return t.Width > Size || t.Height > Size
// Uncached tests if thumbnail type exceeds the cached thumbnails size limit.
func (s Size) Uncached() bool {
return s.Width > SizePrecached || s.Height > SizePrecached
}
// ExceedsSizeUncached tests if thumbnail type is too large and can not be rendered at all.
func (t Type) ExceedsSizeUncached() bool {
return t.Width > MaxSize() || t.Height > MaxSize()
}
// OnDemand tests if thumbnail type should not be pre-rendered.
func (t Type) OnDemand() bool {
return t.Width > Size || t.Height > Size
// ExceedsLimit tests if thumbnail type is too large, and can not be rendered at all.
func (s Size) ExceedsLimit() bool {
return s.Width > MaxSize() || s.Height > MaxSize()
}

View file

@ -6,54 +6,37 @@ import (
"github.com/stretchr/testify/assert"
)
func TestType_ExceedsLimit(t *testing.T) {
Size = 1024
func TestSize_ExceedsLimit(t *testing.T) {
SizePrecached = 1024
SizeUncached = 2048
fit4096 := Types["fit_4096"]
assert.True(t, fit4096.ExceedsSizeUncached())
fit4096 := Sizes["fit_4096"]
assert.True(t, fit4096.ExceedsLimit())
fit2048 := Types["fit_2048"]
assert.False(t, fit2048.ExceedsSizeUncached())
fit2048 := Sizes["fit_2048"]
assert.False(t, fit2048.ExceedsLimit())
tile500 := Types["tile_500"]
assert.False(t, tile500.ExceedsSizeUncached())
tile500 := Sizes["tile_500"]
assert.False(t, tile500.ExceedsLimit())
Size = 2048
SizePrecached = 2048
SizeUncached = 7680
}
func TestType_ExceedsSize(t *testing.T) {
Size = 1024
func TestSize_Uncached(t *testing.T) {
SizePrecached = 1024
SizeUncached = 2048
fit4096 := Types["fit_4096"]
assert.True(t, fit4096.ExceedsSize())
fit4096 := Sizes["fit_4096"]
assert.True(t, fit4096.Uncached())
fit2048 := Types["fit_2048"]
assert.True(t, fit2048.ExceedsSize())
fit2048 := Sizes["fit_2048"]
assert.True(t, fit2048.Uncached())
tile500 := Types["tile_500"]
assert.False(t, tile500.ExceedsSize())
tile500 := Sizes["tile_500"]
assert.False(t, tile500.Uncached())
Size = 2048
SizeUncached = 7680
}
func TestType_SkipPreRender(t *testing.T) {
Size = 1024
SizeUncached = 2048
fit4096 := Types["fit_4096"]
assert.True(t, fit4096.OnDemand())
fit2048 := Types["fit_2048"]
assert.True(t, fit2048.OnDemand())
tile500 := Types["tile_500"]
assert.False(t, tile500.OnDemand())
Size = 2048
SizePrecached = 2048
SizeUncached = 7680
}
@ -72,7 +55,7 @@ func TestResampleFilter_Imaging(t *testing.T) {
})
}
func TestFinde(t *testing.T) {
func TestFind(t *testing.T) {
t.Run("2048", func(t *testing.T) {
tName, tType := Find(2048)
assert.Equal(t, "fit_2048", tName)

View file

@ -18,7 +18,7 @@ func TestMain(m *testing.M) {
code := m.Run()
// remove temporary test files
os.RemoveAll("testdata/1")
_ = os.RemoveAll("testdata/1")
os.Exit(code)
}

View file

@ -97,14 +97,14 @@ func (worker *Share) Start() (err error) {
srcFileName := photoprism.FileName(file.File.FileRoot, file.File.FileName)
if a.ShareSize != "" {
thumbType, ok := thumb.Types[a.ShareSize]
size, ok := thumb.Sizes[a.ShareSize]
if !ok {
log.Errorf("share: invalid size %s", a.ShareSize)
continue
}
srcFileName, err = thumb.FromFile(srcFileName, file.File.FileHash, worker.conf.ThumbPath(), thumbType.Width, thumbType.Height, file.File.FileOrientation, thumbType.Options...)
srcFileName, err = thumb.FromFile(srcFileName, file.File.FileHash, worker.conf.ThumbPath(), size.Width, size.Height, file.File.FileOrientation, size.Options...)
if err != nil {
worker.logError(err)