mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-24 16:41:35 -04:00
refactor(thumbnails): merge processor into generator
Processor is now part of the generator. This should make it possible to implement thumbnail generators that do not depend on the 'imaging' module.
This commit is contained in:
committed by
Ralf Haferkamp
parent
08b33627b2
commit
d0ce57dfc2
@@ -13,27 +13,59 @@ import (
|
||||
|
||||
// Generator generates a web friendly file version.
|
||||
type Generator interface {
|
||||
Generate(size image.Rectangle, img interface{}, processor Processor) (interface{}, error)
|
||||
Generate(size image.Rectangle, img interface{}) (interface{}, error)
|
||||
ProcessorID() string
|
||||
}
|
||||
|
||||
// SimpleGenerator is the default image generator and is used for all image types expect gif.
|
||||
type SimpleGenerator struct{}
|
||||
type SimpleGenerator struct {
|
||||
processor Processor
|
||||
}
|
||||
|
||||
func NewSimpleGenerator(filetype, process string) (SimpleGenerator, error) {
|
||||
processor, err := ProcessorFor(filetype, process)
|
||||
if err != nil {
|
||||
return SimpleGenerator{}, err
|
||||
}
|
||||
return SimpleGenerator{processor: processor}, nil
|
||||
}
|
||||
|
||||
// ProcessorID returns the processor identification.
|
||||
func (g SimpleGenerator) ProcessorID() string {
|
||||
return g.processor.ID()
|
||||
}
|
||||
|
||||
// Generate generates a alternative image version.
|
||||
func (g SimpleGenerator) Generate(size image.Rectangle, img interface{}, processor Processor) (interface{}, error) {
|
||||
func (g SimpleGenerator) Generate(size image.Rectangle, img interface{}) (interface{}, error) {
|
||||
m, ok := img.(image.Image)
|
||||
if !ok {
|
||||
return nil, errors.ErrInvalidType
|
||||
}
|
||||
|
||||
return processor.Process(m, size.Dx(), size.Dy(), imaging.Lanczos), nil
|
||||
return g.processor.Process(m, size.Dx(), size.Dy(), imaging.Lanczos), nil
|
||||
}
|
||||
|
||||
// GifGenerator is used to create a web friendly version of the provided gif image.
|
||||
type GifGenerator struct{}
|
||||
type GifGenerator struct {
|
||||
processor Processor
|
||||
}
|
||||
|
||||
func NewGifGenerator(filetype, process string) (GifGenerator, error) {
|
||||
processor, err := ProcessorFor(filetype, process)
|
||||
if err != nil {
|
||||
return GifGenerator{}, err
|
||||
}
|
||||
return GifGenerator{processor: processor}, nil
|
||||
|
||||
}
|
||||
|
||||
// ProcessorID returns the processor identification.
|
||||
func (g GifGenerator) ProcessorID() string {
|
||||
return g.processor.ID()
|
||||
}
|
||||
|
||||
// Generate generates a alternative gif version.
|
||||
func (g GifGenerator) Generate(size image.Rectangle, img interface{}, processor Processor) (interface{}, error) {
|
||||
func (g GifGenerator) Generate(size image.Rectangle, img interface{}) (interface{}, error) {
|
||||
// Code inspired by https://github.com/willnorris/gifresize/blob/db93a7e1dcb1c279f7eeb99cc6d90b9e2e23e871/gifresize.go
|
||||
|
||||
m, ok := img.(*gif.GIF)
|
||||
@@ -49,7 +81,7 @@ func (g GifGenerator) Generate(size image.Rectangle, img interface{}, processor
|
||||
bounds := frame.Bounds()
|
||||
prev := tmp
|
||||
draw.Draw(tmp, bounds, frame, bounds.Min, draw.Over)
|
||||
processed := processor.Process(tmp, size.Dx(), size.Dy(), imaging.Lanczos)
|
||||
processed := g.processor.Process(tmp, size.Dx(), size.Dy(), imaging.Lanczos)
|
||||
m.Image[i] = g.imageToPaletted(processed, frame.Palette)
|
||||
|
||||
switch m.Disposal[i] {
|
||||
@@ -72,14 +104,14 @@ func (g GifGenerator) imageToPaletted(img image.Image, p color.Palette) *image.P
|
||||
return pm
|
||||
}
|
||||
|
||||
// GeneratorForType returns the generator for a given file type
|
||||
// GeneratorFor returns the generator for a given file type
|
||||
// or nil if the type is not supported.
|
||||
func GeneratorForType(fileType string) (Generator, error) {
|
||||
func GeneratorFor(fileType, processorID string) (Generator, error) {
|
||||
switch strings.ToLower(fileType) {
|
||||
case typePng, typeJpg, typeJpeg, typeGgs:
|
||||
return SimpleGenerator{}, nil
|
||||
return NewSimpleGenerator(fileType, processorID)
|
||||
case typeGif:
|
||||
return GifGenerator{}, nil
|
||||
return NewGifGenerator(fileType, processorID)
|
||||
default:
|
||||
return nil, errors.ErrNoEncoderForType
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ type Request struct {
|
||||
Encoder Encoder
|
||||
Generator Generator
|
||||
Checksum string
|
||||
Processor Processor
|
||||
}
|
||||
|
||||
// Manager is responsible for generating thumbnails
|
||||
@@ -86,7 +85,7 @@ func (s SimpleManager) Generate(r Request, img interface{}) (string, error) {
|
||||
return "", errors.ErrImageTooLarge
|
||||
}
|
||||
|
||||
thumbnail, err := r.Generator.Generate(match, img, r.Processor)
|
||||
thumbnail, err := r.Generator.Generate(match, img)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -120,7 +119,7 @@ func mapToStorageRequest(r Request) storage.Request {
|
||||
Checksum: r.Checksum,
|
||||
Resolution: r.Resolution,
|
||||
Types: r.Encoder.Types(),
|
||||
Characteristic: r.Processor.ID(),
|
||||
Characteristic: r.Generator.ProcessorID(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +135,7 @@ func IsMimeTypeSupported(m string) bool {
|
||||
|
||||
// PrepareRequest prepare the request based on image parameters
|
||||
func PrepareRequest(width, height int, tType, checksum, pID string) (Request, error) {
|
||||
generator, err := GeneratorForType(tType)
|
||||
generator, err := GeneratorFor(tType, pID)
|
||||
if err != nil {
|
||||
return Request{}, err
|
||||
}
|
||||
@@ -144,16 +143,11 @@ func PrepareRequest(width, height int, tType, checksum, pID string) (Request, er
|
||||
if err != nil {
|
||||
return Request{}, err
|
||||
}
|
||||
processor, err := ProcessorFor(pID, tType)
|
||||
if err != nil {
|
||||
return Request{}, err
|
||||
}
|
||||
|
||||
return Request{
|
||||
Resolution: image.Rect(0, 0, width, height),
|
||||
Generator: generator,
|
||||
Encoder: encoder,
|
||||
Checksum: checksum,
|
||||
Processor: processor,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package thumbnail
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/v2/services/thumbnails/pkg/errors"
|
||||
"github.com/owncloud/ocis/v2/services/thumbnails/pkg/preprocessor"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"image"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/owncloud/ocis/v2/services/thumbnails/pkg/errors"
|
||||
"github.com/owncloud/ocis/v2/services/thumbnails/pkg/preprocessor"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
|
||||
@@ -131,11 +133,13 @@ func TestPrepareRequest(t *testing.T) {
|
||||
t.Errorf("PrepareRequest() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
// funcs are not reflactable, ignore
|
||||
if diff := cmp.Diff(tt.want, got, cmpopts.IgnoreFields(Request{}, "Processor")); diff != "" {
|
||||
if diff := cmp.Diff(tt.want, got, cmpopts.IgnoreFields(Request{}, "Generator")); diff != "" {
|
||||
t.Errorf("PrepareRequest(): %v", diff)
|
||||
}
|
||||
if reflect.TypeOf(got.Generator) != reflect.TypeOf(tt.want.Generator) {
|
||||
t.Errorf("PrepareRequest() = %v, want %v", reflect.TypeOf(got.Generator), reflect.TypeOf(tt.want.Generator))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user