feat(thumbnails): optional libvips based thumbnail generation

Can be enabled by setting the 'enable_vips' tag on 'go build'
This commit is contained in:
Ralf Haferkamp
2024-10-14 17:46:30 +02:00
committed by Ralf Haferkamp
parent 358adc15dc
commit a9a5570050
58 changed files with 7324 additions and 0 deletions

View File

@@ -1,3 +1,5 @@
//go:build !enable_vips
package preprocessor
import (

View File

@@ -0,0 +1,20 @@
//go:build enable_vips
package preprocessor
import (
"io"
"github.com/davidbyttow/govips/v2/vips"
)
func init() {
vips.LoggingSettings(nil, vips.LogLevelError)
}
type ImageDecoder struct{}
func (v ImageDecoder) Convert(r io.Reader) (interface{}, error) {
img, err := vips.NewImageFromReader(r)
return img, err
}

View File

@@ -1,3 +1,5 @@
//go:build !enable_vips
package thumbnail
import (

View File

@@ -0,0 +1,66 @@
//go:build enable_vips
package thumbnail
import (
"io"
"github.com/davidbyttow/govips/v2/vips"
"github.com/owncloud/ocis/v2/services/thumbnails/pkg/errors"
)
// PngEncoder encodes to png
type PngEncoder struct{}
// Encode encodes to png format
func (e PngEncoder) Encode(w io.Writer, img interface{}) error {
m, ok := img.(*vips.ImageRef)
if !ok {
return errors.ErrInvalidType
}
buf, _, err := m.ExportPng(vips.NewPngExportParams())
if err != nil {
return err
}
_, err = w.Write(buf)
return err
}
// Types returns the png suffix
func (e PngEncoder) Types() []string {
return []string{typePng}
}
// MimeType returns the mimetype for png files.
func (e PngEncoder) MimeType() string {
return "image/png"
}
// JpegEncoder encodes to jpg
type JpegEncoder struct{}
// Encode encodes to jpg
func (e JpegEncoder) Encode(w io.Writer, img interface{}) error {
m, ok := img.(*vips.ImageRef)
if !ok {
return errors.ErrInvalidType
}
buf, _, err := m.ExportJpeg(vips.NewJpegExportParams())
if err != nil {
return err
}
_, err = w.Write(buf)
return err
}
// Types returns the jpg suffixes.
func (e JpegEncoder) Types() []string {
return []string{typeJpeg, typeJpg}
}
// MimeType returns the mimetype for jpg files.
func (e JpegEncoder) MimeType() string {
return "image/jpeg"
}

View File

@@ -1,3 +1,5 @@
//go:build !enable_vips
package thumbnail
import (

View File

@@ -0,0 +1,62 @@
//go:build enable_vips
package thumbnail
import (
"image"
"strings"
"github.com/davidbyttow/govips/v2/vips"
"github.com/owncloud/ocis/v2/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.InterestingNone, process: process}, 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) {
m, ok := img.(*vips.ImageRef)
if !ok {
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) {
m, ok := img.(*vips.ImageRef)
if !ok {
return image.Rectangle{}, errors.ErrInvalidType
}
return image.Rect(0, 0, m.Width(), m.Height()), nil
}