mirror of
				https://github.com/imgproxy/imgproxy.git
				synced 2025-10-30 23:08:02 +02:00 
			
		
		
		
	format_quality processing option
This commit is contained in:
		| @@ -11,6 +11,7 @@ | |||||||
| - [Datadog](./docs/datadog.md) metrics. | - [Datadog](./docs/datadog.md) metrics. | ||||||
| - `force` and `fill-down` resizing types. | - `force` and `fill-down` resizing types. | ||||||
| - [min-width](https://docs.imgproxy.net/generating_the_url?id=min-width) and [min-height](https://docs.imgproxy.net/generating_the_url?id=min-height) processing options. | - [min-width](https://docs.imgproxy.net/generating_the_url?id=min-width) and [min-height](https://docs.imgproxy.net/generating_the_url?id=min-height) processing options. | ||||||
|  | - [format_quality](https://docs.imgproxy.net/generating_the_url?id=format-quality) processing option. | ||||||
|  |  | ||||||
| ### Removed | ### Removed | ||||||
| - Removed basic URL format, use [advanced one](./docs/generating_the_url.md) instead. | - Removed basic URL format, use [advanced one](./docs/generating_the_url.md) instead. | ||||||
|   | |||||||
| @@ -466,10 +466,19 @@ quality:%quality | |||||||
| q:%quality | q:%quality | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Redefines quality of the resulting image, percentage. When `0`, quality is assumed based on `IMGPROXY_QUALITY` and `IMGPROXY_FORMAT_QUALITY`. | Redefines quality of the resulting image, percentage. When `0`, quality is assumed based on `IMGPROXY_QUALITY` and [format_quality](#format-quality). | ||||||
|  |  | ||||||
| Default: 0. | Default: 0. | ||||||
|  |  | ||||||
|  | ### Format quality | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | format_quality:%format1:%quality1:%format2:%quality2:...:%formatN:%qualityN | ||||||
|  | fq:%format1:%quality1:%format2:%quality2:...:%formatN:%qualityN | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Adds or redefines `IMGPROXY_FORMAT_QUALITY` values. | ||||||
|  |  | ||||||
| ### Autoquality | ### Autoquality | ||||||
|  |  | ||||||
| ``` | ``` | ||||||
|   | |||||||
| @@ -79,6 +79,7 @@ type ProcessingOptions struct { | |||||||
| 	Rotate            int | 	Rotate            int | ||||||
| 	Format            imagetype.Type | 	Format            imagetype.Type | ||||||
| 	Quality           int | 	Quality           int | ||||||
|  | 	FormatQuality     map[imagetype.Type]int | ||||||
| 	MaxBytes          int | 	MaxBytes          int | ||||||
| 	Flatten           bool | 	Flatten           bool | ||||||
| 	Background        vips.Color | 	Background        vips.Color | ||||||
| @@ -103,6 +104,8 @@ type ProcessingOptions struct { | |||||||
| 	Filename string | 	Filename string | ||||||
|  |  | ||||||
| 	UsedPresets []string | 	UsedPresets []string | ||||||
|  |  | ||||||
|  | 	defaultQuality int | ||||||
| } | } | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| @@ -133,6 +136,9 @@ func NewProcessingOptions() *ProcessingOptions { | |||||||
| 			StripMetadata:     config.StripMetadata, | 			StripMetadata:     config.StripMetadata, | ||||||
| 			StripColorProfile: config.StripColorProfile, | 			StripColorProfile: config.StripColorProfile, | ||||||
| 			AutoRotate:        config.AutoRotate, | 			AutoRotate:        config.AutoRotate, | ||||||
|  |  | ||||||
|  | 			// Basically, we need this to update ETag when `IMGPROXY_QUALITY` is changed | ||||||
|  | 			defaultQuality: config.Quality, | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| @@ -140,6 +146,11 @@ func NewProcessingOptions() *ProcessingOptions { | |||||||
| 	po.SkipProcessingFormats = append([]imagetype.Type(nil), config.SkipProcessingFormats...) | 	po.SkipProcessingFormats = append([]imagetype.Type(nil), config.SkipProcessingFormats...) | ||||||
| 	po.UsedPresets = make([]string, 0, len(config.Presets)) | 	po.UsedPresets = make([]string, 0, len(config.Presets)) | ||||||
|  |  | ||||||
|  | 	po.FormatQuality = make(map[imagetype.Type]int) | ||||||
|  | 	for k, v := range config.FormatQuality { | ||||||
|  | 		po.FormatQuality[k] = v | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return &po | 	return &po | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -147,11 +158,11 @@ func (po *ProcessingOptions) GetQuality() int { | |||||||
| 	q := po.Quality | 	q := po.Quality | ||||||
|  |  | ||||||
| 	if q == 0 { | 	if q == 0 { | ||||||
| 		q = config.FormatQuality[po.Format] | 		q = po.FormatQuality[po.Format] | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if q == 0 { | 	if q == 0 { | ||||||
| 		q = config.Quality | 		q = po.defaultQuality | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return q | 	return q | ||||||
| @@ -522,6 +533,28 @@ func applyQualityOption(po *ProcessingOptions, args []string) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func applyFormatQualityOption(po *ProcessingOptions, args []string) error { | ||||||
|  | 	argsLen := len(args) | ||||||
|  | 	if len(args)%2 != 0 { | ||||||
|  | 		return fmt.Errorf("Missing quality for: %s", args[argsLen-1]) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for i := 0; i < argsLen; i += 2 { | ||||||
|  | 		f, ok := imagetype.Types[args[i]] | ||||||
|  | 		if !ok { | ||||||
|  | 			return fmt.Errorf("Invalid image format: %s", args[i]) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if q, err := strconv.Atoi(args[i+1]); err == nil && q >= 0 && q <= 100 { | ||||||
|  | 			po.FormatQuality[f] = q | ||||||
|  | 		} else { | ||||||
|  | 			return fmt.Errorf("Invalid quality for %s: %s", args[i], args[i+1]) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
| func applyMaxBytesOption(po *ProcessingOptions, args []string) error { | func applyMaxBytesOption(po *ProcessingOptions, args []string) error { | ||||||
| 	if len(args) > 1 { | 	if len(args) > 1 { | ||||||
| 		return fmt.Errorf("Invalid max_bytes arguments: %v", args) | 		return fmt.Errorf("Invalid max_bytes arguments: %v", args) | ||||||
| @@ -832,6 +865,8 @@ func applyURLOption(po *ProcessingOptions, name string, args []string) error { | |||||||
| 	// Saving options | 	// Saving options | ||||||
| 	case "quality", "q": | 	case "quality", "q": | ||||||
| 		return applyQualityOption(po, args) | 		return applyQualityOption(po, args) | ||||||
|  | 	case "format_quality", "fq": | ||||||
|  | 		return applyFormatQualityOption(po, args) | ||||||
| 	case "max_bytes", "mb": | 	case "max_bytes", "mb": | ||||||
| 		return applyMaxBytesOption(po, args) | 		return applyMaxBytesOption(po, args) | ||||||
| 	case "format", "f", "ext": | 	case "format", "f", "ext": | ||||||
|   | |||||||
| @@ -94,6 +94,10 @@ func Diff(a, b interface{}) Entries { | |||||||
| 		fieldA := valA.Field(i) | 		fieldA := valA.Field(i) | ||||||
| 		fieldB := valB.Field(i) | 		fieldB := valB.Field(i) | ||||||
|  |  | ||||||
|  | 		if !fieldA.CanInterface() || !fieldB.CanInterface() { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		intA := fieldA.Interface() | 		intA := fieldA.Interface() | ||||||
| 		intB := fieldB.Interface() | 		intB := fieldB.Interface() | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user