1
0
Эх сурвалжийг харах

Per-format default quality config

DarthSim 4 жил өмнө
parent
commit
c84e7ed34d

+ 1 - 0
CHANGELOG.md

@@ -5,6 +5,7 @@
 - AVIF support.
 - Azure Blob Storage support.
 - `IMGPROXY_STRIP_COLOR_PROFILE` config and [strip_color_profile](https://docs.imgproxy.net/#/generating_the_url_advanced?id=strip-color-profile) processing option.
+- `IMGPROXY_FORMAT_QUALITY` config.
 - (pro) Remove Adobe Illustrator garbage from SVGs.
 
 ### Changed

+ 31 - 0
config.go

@@ -75,6 +75,34 @@ func imageTypesEnvConfig(it *[]imageType, name string) {
 	}
 }
 
+func formatQualityEnvConfig(m map[imageType]int, name string) {
+	if env := os.Getenv(name); len(env) > 0 {
+		parts := strings.Split(env, ",")
+
+		for _, p := range parts {
+			i := strings.Index(p, "=")
+			if i < 0 {
+				logWarning("Invalid format quality string: %s", p)
+				continue
+			}
+
+			imgtypeStr, qStr := strings.TrimSpace(p[:i]), strings.TrimSpace(p[i+1:])
+
+			imgtype, ok := imageTypes[imgtypeStr]
+			if !ok {
+				logWarning("Invalid format: %s", p)
+			}
+
+			q, err := strconv.Atoi(qStr)
+			if err != nil || q <= 0 || q > 100 {
+				logWarning("Invalid quality: %s", p)
+			}
+
+			m[imgtype] = q
+		}
+	}
+}
+
 func hexEnvConfig(b *[]securityKey, name string) error {
 	var err error
 
@@ -197,6 +225,7 @@ type config struct {
 	PngQuantize           bool
 	PngQuantizationColors int
 	Quality               int
+	FormatQuality         map[imageType]int
 	GZipCompression       int
 	StripMetadata         bool
 	StripColorProfile     bool
@@ -291,6 +320,7 @@ var conf = config{
 	SignatureSize:                  32,
 	PngQuantizationColors:          256,
 	Quality:                        80,
+	FormatQuality:                  map[imageType]int{imageTypeAVIF: 50},
 	StripMetadata:                  true,
 	StripColorProfile:              true,
 	UserAgent:                      fmt.Sprintf("imgproxy/%s", version),
@@ -349,6 +379,7 @@ func configure() error {
 	boolEnvConfig(&conf.PngQuantize, "IMGPROXY_PNG_QUANTIZE")
 	intEnvConfig(&conf.PngQuantizationColors, "IMGPROXY_PNG_QUANTIZATION_COLORS")
 	intEnvConfig(&conf.Quality, "IMGPROXY_QUALITY")
+	formatQualityEnvConfig(conf.FormatQuality, "IMGPROXY_FORMAT_QUALITY")
 	intEnvConfig(&conf.GZipCompression, "IMGPROXY_GZIP_COMPRESSION")
 	boolEnvConfig(&conf.StripMetadata, "IMGPROXY_STRIP_METADATA")
 	boolEnvConfig(&conf.StripColorProfile, "IMGPROXY_STRIP_COLOR_PROFILE")

+ 1 - 0
docs/configuration.md

@@ -87,6 +87,7 @@ Also you may want imgproxy to respond with the same error message that it writes
 ## Compression
 
 * `IMGPROXY_QUALITY`: default quality of the resulting image, percentage. Default: `80`;
+* `IMGPROXY_FORMAT_QUALITY`: default quality of the resulting image per format, comma divided. Example: `jpeg=70,avif=40,webp=60`. When value for the resulting format is not set, `IMGPROXY_QUALITY` value is used. Default: `avif=50`.
 * `IMGPROXY_GZIP_COMPRESSION`: GZip compression level. Default: `5`.
 
 ### Advanced JPEG compression

+ 2 - 2
docs/generating_the_url_advanced.md

@@ -215,9 +215,9 @@ quality:%quality
 q:%quality
 ```
 
-Redefines quality of the resulting image, percentage.
+Redefines quality of the resulting image, percentage. When `0`, quality is assumed based on `IMGPROXY_QUALITY` and `IMGPROXY_FORMAT_QUALITY`.
 
-Default: value from the environment variable.
+Default: 0.
 
 #### Max Bytes
 

+ 2 - 2
process.go

@@ -678,7 +678,7 @@ func getIcoData(imgdata *imageData) (*imageData, error) {
 
 func saveImageToFitBytes(po *processingOptions, img *vipsImage) ([]byte, context.CancelFunc, error) {
 	var diff float64
-	quality := po.Quality
+	quality := po.getQuality()
 
 	img.CopyMemory()
 
@@ -806,5 +806,5 @@ func processImage(ctx context.Context) ([]byte, context.CancelFunc, error) {
 		return saveImageToFitBytes(po, img)
 	}
 
-	return img.Save(po.Format, po.Quality)
+	return img.Save(po.Format, po.getQuality())
 }

+ 16 - 2
processing_options.go

@@ -221,7 +221,7 @@ func newProcessingOptions() *processingOptions {
 			Extend:            extendOptions{Enabled: false, Gravity: gravityOptions{Type: gravityCenter}},
 			Padding:           paddingOptions{Enabled: false},
 			Trim:              trimOptions{Enabled: false, Threshold: 10, Smart: true},
-			Quality:           conf.Quality,
+			Quality:           0,
 			MaxBytes:          0,
 			Format:            imageTypeUnknown,
 			Background:        rgbColor{255, 255, 255},
@@ -240,6 +240,20 @@ func newProcessingOptions() *processingOptions {
 	return &po
 }
 
+func (po *processingOptions) getQuality() int {
+	q := po.Quality
+
+	if q == 0 {
+		q = conf.FormatQuality[po.Format]
+	}
+
+	if q == 0 {
+		q = conf.Quality
+	}
+
+	return q
+}
+
 func (po *processingOptions) isPresetUsed(name string) bool {
 	for _, usedName := range po.UsedPresets {
 		if usedName == name {
@@ -653,7 +667,7 @@ func applyQualityOption(po *processingOptions, args []string) error {
 		return fmt.Errorf("Invalid quality arguments: %v", args)
 	}
 
-	if q, err := strconv.Atoi(args[0]); err == nil && q > 0 && q <= 100 {
+	if q, err := strconv.Atoi(args[0]); err == nil && q >= 0 && q <= 100 {
 		po.Quality = q
 	} else {
 		return fmt.Errorf("Invalid quality: %s", args[0])