Files
imgproxy/processing/options.go
2025-09-24 00:41:12 +06:00

282 lines
7.3 KiB
Go

package processing
import (
"slices"
"github.com/imgproxy/imgproxy/v3/imagetype"
"github.com/imgproxy/imgproxy/v3/options"
"github.com/imgproxy/imgproxy/v3/options/keys"
"github.com/imgproxy/imgproxy/v3/vips/color"
)
// ProcessingOptions is a thin wrapper around options.Options that provides
// helpers for image processing options.
type ProcessingOptions struct {
*options.Options
// Config that contains default values for some options.
config *Config
}
func (p *Processor) NewProcessingOptions(o *options.Options) ProcessingOptions {
return ProcessingOptions{
Options: o,
config: p.config,
}
}
func (po ProcessingOptions) Width() int {
return po.GetInt(keys.Width, 0)
}
func (po ProcessingOptions) Height() int {
return po.GetInt(keys.Height, 0)
}
func (po ProcessingOptions) MinWidth() int {
return po.GetInt(keys.MinWidth, 0)
}
func (po ProcessingOptions) MinHeight() int {
return po.GetInt(keys.MinHeight, 0)
}
func (po ProcessingOptions) ResizingType() options.ResizeType {
return options.Get(po.Options, keys.ResizingType, options.ResizeFit)
}
func (po ProcessingOptions) ZoomWidth() float64 {
return po.GetFloat(keys.ZoomWidth, 1.0)
}
func (po ProcessingOptions) ZoomHeight() float64 {
return po.GetFloat(keys.ZoomHeight, 1.0)
}
func (po ProcessingOptions) DPR() float64 {
return po.GetFloat(keys.Dpr, 1.0)
}
func (po ProcessingOptions) EnforceThumbnail() bool {
return po.Main().GetBool(keys.EnforceThumbnail, po.config.EnforceThumbnail)
}
func (po ProcessingOptions) Enlarge() bool {
return po.GetBool(keys.Enlarge, false)
}
func (po ProcessingOptions) Gravity() GravityOptions {
return NewGravityOptions(po, keys.Gravity, options.GravityCenter)
}
func (po ProcessingOptions) ExtendEnabled() bool {
return po.GetBool(keys.ExtendEnabled, false)
}
func (po ProcessingOptions) ExtendGravity() GravityOptions {
return NewGravityOptions(po, keys.ExtendGravity, options.GravityCenter)
}
func (po ProcessingOptions) ExtendAspectRatioEnabled() bool {
return po.GetBool(keys.ExtendAspectRatioEnabled, false)
}
func (po ProcessingOptions) ExtendAspectRatioGravity() GravityOptions {
return NewGravityOptions(po, keys.ExtendAspectRatioGravity, options.GravityCenter)
}
func (po ProcessingOptions) Rotate() int {
return po.GetInt(keys.Rotate, 0)
}
func (po ProcessingOptions) AutoRotate() bool {
return po.GetBool(keys.AutoRotate, po.config.AutoRotate)
}
func (po ProcessingOptions) CropWidth() float64 {
return po.GetFloat(keys.CropWidth, 0.0)
}
func (po ProcessingOptions) CropHeight() float64 {
return po.GetFloat(keys.CropHeight, 0.0)
}
func (po ProcessingOptions) CropGravity() GravityOptions {
return NewGravityOptions(po, keys.CropGravity, options.GravityUnknown)
}
func (po ProcessingOptions) Format() imagetype.Type {
return options.Get(po.Main(), keys.Format, imagetype.Unknown)
}
func (po ProcessingOptions) SetFormat(format imagetype.Type) {
po.Set(keys.Format, format)
}
func (po ProcessingOptions) ShouldSkipFormatProcessing(inFormat imagetype.Type) bool {
return slices.Contains(po.config.SkipProcessingFormats, inFormat) ||
options.SliceContains(po.Main(), keys.SkipProcessing, inFormat)
}
func (po ProcessingOptions) ShouldFlatten() bool {
return po.Has(keys.Background)
}
func (po ProcessingOptions) Background() color.RGB {
return options.Get(po.Options, keys.Background, color.RGB{R: 255, G: 255, B: 255})
}
func (po ProcessingOptions) PaddingEnabled() bool {
return po.PaddingTop() != 0 ||
po.PaddingRight() != 0 ||
po.PaddingBottom() != 0 ||
po.PaddingLeft() != 0
}
func (po ProcessingOptions) PaddingTop() int {
return po.GetInt(keys.PaddingTop, 0)
}
func (po ProcessingOptions) PaddingRight() int {
return po.GetInt(keys.PaddingRight, 0)
}
func (po ProcessingOptions) PaddingBottom() int {
return po.GetInt(keys.PaddingBottom, 0)
}
func (po ProcessingOptions) PaddingLeft() int {
return po.GetInt(keys.PaddingLeft, 0)
}
func (po ProcessingOptions) Blur() float64 {
return po.GetFloat(keys.Blur, 0.0)
}
func (po ProcessingOptions) Sharpen() float64 {
return po.GetFloat(keys.Sharpen, 0.0)
}
func (po ProcessingOptions) Pixelate() int {
return po.GetInt(keys.Pixelate, 1)
}
func (po ProcessingOptions) PreferWebP() bool {
return po.GetBool(keys.PreferWebP, false)
}
func (po ProcessingOptions) PreferAvif() bool {
return po.GetBool(keys.PreferAvif, false)
}
func (po ProcessingOptions) PreferJxl() bool {
return po.GetBool(keys.PreferJxl, false)
}
func (po ProcessingOptions) EnforceWebP() bool {
return po.GetBool(keys.EnforceWebP, false)
}
func (po ProcessingOptions) EnforceAvif() bool {
return po.GetBool(keys.EnforceAvif, false)
}
func (po ProcessingOptions) EnforceJxl() bool {
return po.GetBool(keys.EnforceJxl, false)
}
func (po ProcessingOptions) TrimEnabled() bool {
return po.Has(keys.TrimThreshold)
}
func (po ProcessingOptions) DisableTrim() {
po.Delete(keys.TrimThreshold)
}
func (po ProcessingOptions) TrimThreshold() float64 {
return po.GetFloat(keys.TrimThreshold, 10.0)
}
func (po ProcessingOptions) TrimSmart() bool {
return !po.Has(keys.TrimColor)
}
func (po ProcessingOptions) TrimColor() color.RGB {
return options.Get(po.Options, keys.TrimColor, color.RGB{})
}
func (po ProcessingOptions) TrimEqualHor() bool {
return po.GetBool(keys.TrimEqualHor, false)
}
func (po ProcessingOptions) TrimEqualVer() bool {
return po.GetBool(keys.TrimEqualVer, false)
}
func (po ProcessingOptions) WatermarkOpacity() float64 {
return po.GetFloat(keys.WatermarkOpacity, 0.0)
}
func (po ProcessingOptions) SetWatermarkOpacity(opacity float64) {
po.Set(keys.WatermarkOpacity, opacity)
}
func (po ProcessingOptions) DeleteWatermarkOpacity() {
po.Delete(keys.WatermarkOpacity)
}
func (po ProcessingOptions) WatermarkPosition() options.GravityType {
return options.Get(po.Options, keys.WatermarkPosition, options.GravityCenter)
}
func (po ProcessingOptions) WatermarkXOffset() float64 {
return po.GetFloat(keys.WatermarkXOffset, 0.0)
}
func (po ProcessingOptions) WatermarkYOffset() float64 {
return po.GetFloat(keys.WatermarkYOffset, 0.0)
}
func (po ProcessingOptions) WatermarkScale() float64 {
return po.GetFloat(keys.WatermarkScale, 0.0)
}
// Quality retrieves the quality setting for a given image format.
// It first checks for a general quality setting, then for a format-specific setting,
// and finally falls back to the configured default quality.
func (po ProcessingOptions) Quality(format imagetype.Type) int {
// First, check if quality is explicitly set in options.
if q := po.Main().GetInt(keys.Quality, 0); q > 0 {
return q
}
// Then, check if format-specific quality is set in options.
if q := po.Main().GetInt(keys.FormatQuality(format), 0); q > 0 {
return q
}
// Then, check if format-specific quality is set in config.
if q := po.config.FormatQuality[format]; q > 0 {
return q
}
// Finally, return the general quality setting from config.
return po.config.Quality
}
func (po ProcessingOptions) MaxBytes() int {
return po.Main().GetInt(keys.MaxBytes, 0)
}
func (po ProcessingOptions) StripMetadata() bool {
return po.Main().GetBool(keys.StripMetadata, po.config.StripMetadata)
}
func (po ProcessingOptions) KeepCopyright() bool {
return po.Main().GetBool(keys.KeepCopyright, po.config.KeepCopyright)
}
func (po ProcessingOptions) StripColorProfile() bool {
return po.Main().GetBool(keys.StripColorProfile, po.config.StripColorProfile)
}