func presetToTransform(preset config.Preset) (transforms.Transforms, error) {
	trans := transforms.New()
	filters := preset.Filters
	if filters.Thumbnail != nil {
		err := trans.Resize(filters.Thumbnail.Width, filters.Thumbnail.Height, filters.Thumbnail.Mode == "outbound", filters.Thumbnail.PreserveAspectRatio, filters.Thumbnail.Fill)
		if err != nil {
			return trans, err
		}
	}
	if filters.Crop != nil {
		err := trans.Crop(filters.Crop.Width, filters.Crop.Height, filters.Crop.Gravity, filters.Crop.Mode == "outbound", filters.Crop.Embed)
		if err != nil {
			return trans, err
		}
	}
	if filters.Extract != nil {
		err := trans.Extract(filters.Extract.Top, filters.Extract.Left, filters.Extract.Width, filters.Extract.Height)
		if err != nil {
			return trans, err
		}
	}
	if filters.ResizeCropAuto != nil {
		err := trans.ResizeCropAuto(filters.ResizeCropAuto.Width, filters.ResizeCropAuto.Height)
		if err != nil {
			return trans, err
		}
	}
	trans.Quality(preset.Quality)
	if filters.Interlace == true {
		err := trans.Interlace()
		if err != nil {
			return trans, err
		}
	}
	if filters.Strip == true {
		err := trans.StripMetadata()
		if err != nil {
			return trans, err
		}
	}
	if preset.Format != "" {
		err := trans.Format(preset.Format)
		if err != nil {
			return trans, err
		}
	}
	if filters.Blur != nil {
		err := trans.Blur(filters.Blur.Sigma, filters.Blur.MinAmpl)
		if err != nil {
			return trans, err
		}
	}
	if filters.Watermark != nil {
		err := trans.Watermark(filters.Watermark.Image, filters.Watermark.Position, filters.Watermark.Opacity)
		if err != nil {
			return trans, err
		}
	}
	if filters.Grayscale {
		trans.Grayscale()
	}
	if filters.Rotate != nil {
		trans.Rotate(filters.Rotate.Angle)
	}
	return trans, nil
}
presetToTransform convert preset config to transform
nolint: gocyclo
package object
import (
	"errors"
	"github.com/aldor007/mort/pkg/config"
	"github.com/aldor007/mort/pkg/monitoring"
	"github.com/aldor007/mort/pkg/transforms"
	"net/url"
	"path"
	"strings"
	"sync"
	"go.uber.org/zap"
)
func init() {
	RegisterParser("presets", decodePreset)
}
var presetCache = make(map[string]transforms.Transforms)
var presetCacheLock = sync.RWMutex{}
func decodePreset(_ *url.URL, bucketConfig config.Bucket, obj *FileObject) (string, error) {
	trans := bucketConfig.Transform
	matches := trans.PathRegexp.FindStringSubmatch(obj.Key)
	if matches == nil {
		return "", nil
	}
	subMatchMap := make(map[string]string, 2)
	for i, name := range trans.PathRegexp.SubexpNames() {
		if i != 0 && name != "" {
			subMatchMap[name] = matches[i]
		}
	}
	presetName := subMatchMap["presetName"]
	parent := subMatchMap["parent"]
	if _, ok := trans.Presets[presetName]; !ok {
		monitoring.Log().Warn("FileObject decodePreset unknown preset", zap.String("obj.path", obj.Uri.Path), zap.String("obj.Key", obj.Key), zap.String("parent", parent), zap.String("presetName", presetName),
			zap.String("regexp", trans.Path))
		return "", errors.New("unknown preset " + presetName)
	}
	var err error
	presetCacheLock.RLock()
	if t, ok := presetCache[presetName]; ok {
		obj.Transforms = t
		presetCacheLock.RUnlock()
	} else {
		presetCacheLock.RUnlock()
		obj.Transforms, err = presetToTransform(trans.Presets[presetName])
		if err != nil {
			return parent, err
		}
		presetCacheLock.Lock()
		presetCache[presetName] = obj.Transforms
		presetCacheLock.Unlock()
	}
	if trans.ParentBucket != "" {
		parent = "/" + path.Join(trans.ParentBucket, parent)
	} else if !strings.HasPrefix(parent, "/") {
		parent = "/" + parent
	}
	return parent, err
}