chore: update thumbnail generator

This commit is contained in:
Steven 2024-09-03 22:09:02 +08:00
parent 09586d032c
commit 773ab96bd0

View file

@ -5,14 +5,12 @@ import (
"context" "context"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"image"
"io" "io"
"log/slog" "log/slog"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings" "strings"
"sync/atomic"
"time" "time"
"github.com/disintegration/imaging" "github.com/disintegration/imaging"
@ -409,6 +407,11 @@ func (s *APIV1Service) GetResourceBlob(resource *store.Resource) ([]byte, error)
return blob, nil return blob, nil
} }
const (
// thumbnailMaxWidth is the maximum width of the thumbnail image.
thumbnailMaxWidth = 700
)
// getOrGenerateThumbnail returns the thumbnail image of the resource. // getOrGenerateThumbnail returns the thumbnail image of the resource.
func (s *APIV1Service) getOrGenerateThumbnail(resource *store.Resource) ([]byte, error) { func (s *APIV1Service) getOrGenerateThumbnail(resource *store.Resource) ([]byte, error) {
thumbnailCacheFolder := filepath.Join(s.Profile.Data, ThumbnailCacheFolder) thumbnailCacheFolder := filepath.Join(s.Profile.Data, ThumbnailCacheFolder)
@ -421,16 +424,7 @@ func (s *APIV1Service) getOrGenerateThumbnail(resource *store.Resource) ([]byte,
return nil, errors.Wrap(err, "failed to check thumbnail image stat") return nil, errors.Wrap(err, "failed to check thumbnail image stat")
} }
var availableGeneratorAmount int32 = 32 // If thumbnail image does not exist, generate and save the thumbnail image.
if atomic.LoadInt32(&availableGeneratorAmount) <= 0 {
return nil, errors.New("not enough available generator amount")
}
atomic.AddInt32(&availableGeneratorAmount, -1)
defer func() {
atomic.AddInt32(&availableGeneratorAmount, 1)
}()
// Otherwise, generate and save the thumbnail image.
blob, err := s.GetResourceBlob(resource) blob, err := s.GetResourceBlob(resource)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to get resource blob") return nil, errors.Wrap(err, "failed to get resource blob")
@ -440,29 +434,28 @@ func (s *APIV1Service) getOrGenerateThumbnail(resource *store.Resource) ([]byte,
return nil, errors.Wrap(err, "failed to decode thumbnail image") return nil, errors.Wrap(err, "failed to decode thumbnail image")
} }
thumbnailMaxWidth := 700 // equal to home/explore screen image max width // If the image is smaller than the thumbnailMaxWidth, return the original image.
var thumbnailImage image.Image if img.Bounds().Max.X < thumbnailMaxWidth {
if img.Bounds().Max.X > thumbnailMaxWidth { return blob, nil
thumbnailImage = imaging.Resize(img, thumbnailMaxWidth, 0, imaging.Lanczos)
} else {
thumbnailImage = img
} }
// Resize the image to the thumbnailMaxWidth.
thumbnailImage := imaging.Resize(img, thumbnailMaxWidth, 0, imaging.Lanczos)
if err := imaging.Save(thumbnailImage, filePath); err != nil { if err := imaging.Save(thumbnailImage, filePath); err != nil {
return nil, errors.Wrap(err, "failed to save thumbnail file") return nil, errors.Wrap(err, "failed to save thumbnail file")
} }
} }
dstFile, err := os.Open(filePath) thumbnailFile, err := os.Open(filePath)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to open thumbnail file") return nil, errors.Wrap(err, "failed to open thumbnail file")
} }
defer dstFile.Close() defer thumbnailFile.Close()
dstBlob, err := io.ReadAll(dstFile) blob, err := io.ReadAll(thumbnailFile)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to read thumbnail file") return nil, errors.Wrap(err, "failed to read thumbnail file")
} }
return dstBlob, nil return blob, nil
} }
var fileKeyPattern = regexp.MustCompile(`\{[a-z]{1,9}\}`) var fileKeyPattern = regexp.MustCompile(`\{[a-z]{1,9}\}`)