Files
QSfera/Server/services/thumbnails/pkg/thumbnail/generator_vips.go
T
Курнат Андрей 7135199f23
Server / deployment-config (push) Successful in 59s
Android / test-and-build (push) Failing after 1m14s
Server / vulnerability-scan (push) Failing after 8m54s
Make photo library offline-first and fix video thumbnails
2026-07-19 21:01:35 +03:00

85 lines
2.3 KiB
Go

//go:build enable_vips
package thumbnail
import (
"bytes"
"image"
"image/png"
"strings"
"github.com/davidbyttow/govips/v2/vips"
"github.com/qsfera/server/services/thumbnails/pkg/errors"
)
// SimpleGenerator is the default image generator and is used for all image types expect gif.
type SimpleGenerator struct {
crop vips.Interesting
size vips.Size
process string
}
func NewSimpleGenerator(filetype, process string) (SimpleGenerator, error) {
switch strings.ToLower(process) {
case "thumbnail":
return SimpleGenerator{crop: vips.InterestingAttention, process: process, size: vips.SizeBoth}, nil
case "fit":
return SimpleGenerator{crop: vips.InterestingNone, process: process, size: vips.SizeBoth}, nil
case "resize":
return SimpleGenerator{crop: vips.InterestingNone, process: process, size: vips.SizeForce}, nil
default:
return SimpleGenerator{crop: vips.InterestingAttention, process: process, size: vips.SizeBoth}, nil
}
}
// ProcessorID returns the processor identification.
func (g SimpleGenerator) ProcessorID() string {
return g.process
}
// Generate generates a alternative image version.
func (g SimpleGenerator) Generate(size image.Rectangle, img interface{}) (interface{}, error) {
var m *vips.ImageRef
var err error
switch typed := img.(type) {
case image.Image:
// Preprocessors for text and video return standard-library image types. Convert
// them to a lossless stream before handing them to libvips; decoded PNG video
// frames are usually *image.NRGBA and were previously rejected as invalid.
var buf bytes.Buffer
if err = png.Encode(&buf, typed); err != nil {
return nil, err
}
m, err = vips.NewImageFromReader(&buf)
if err != nil {
return nil, err
}
case *vips.ImageRef:
m = img.(*vips.ImageRef)
default:
return nil, errors.ErrInvalidType
}
if err := m.ThumbnailWithSize(size.Dx(), 0, g.crop, g.size); err != nil {
return nil, err
}
if err := m.RemoveMetadata(); err != nil {
return nil, err
}
return m, nil
}
func (g SimpleGenerator) Dimensions(img interface{}) (image.Rectangle, error) {
switch typed := img.(type) {
case image.Image:
return typed.Bounds(), nil
case *vips.ImageRef:
return image.Rect(0, 0, typed.Width(), typed.Height()), nil
default:
return image.Rectangle{}, errors.ErrInvalidType
}
}