1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-09-16 09:36:18 +02:00

IMGPROXY_PREFERRED_FORMATS config

This commit is contained in:
DarthSim
2022-07-18 17:49:04 +06:00
parent 9adf06fb04
commit f368ed13e9
6 changed files with 82 additions and 8 deletions

View File

@@ -5,6 +5,7 @@
- Add support of 16-bit BMP.
- Add `IMGPROXY_NEW_RELIC_LABELS` config.
- Add support of JPEG files with differential Huffman coding or arithmetic coding.
- Add `IMGPROXY_PREFERRED_FORMATS` config.
### Fix
- Fix trimming of CMYK images.

View File

@@ -59,6 +59,8 @@ var (
EnforceAvif bool
EnableClientHints bool
PreferredFormats []imagetype.Type
SkipProcessingFormats []imagetype.Type
UseLinearColorspace bool
@@ -220,6 +222,15 @@ func Reset() {
EnforceAvif = false
EnableClientHints = false
PreferredFormats = []imagetype.Type{
imagetype.JPEG,
imagetype.PNG,
imagetype.GIF,
imagetype.WEBP,
imagetype.AVIF,
imagetype.ICO,
}
SkipProcessingFormats = make([]imagetype.Type, 0)
UseLinearColorspace = false
@@ -376,6 +387,10 @@ func Configure() error {
configurators.String(&HealthCheckPath, "IMGPROXY_HEALTH_CHECK_PATH")
if err := configurators.ImageTypes(&PreferredFormats, "IMGPROXY_PREFERRED_FORMATS"); err != nil {
return err
}
if err := configurators.ImageTypes(&SkipProcessingFormats, "IMGPROXY_SKIP_PROCESSING_FORMATS"); err != nil {
return err
}
@@ -557,6 +572,10 @@ func Configure() error {
return fmt.Errorf("Quality can't be greater than 100, now - %d\n", Quality)
}
if len(PreferredFormats) == 0 {
return fmt.Errorf("At least one preferred format should be specified")
}
if IgnoreSslVerification {
log.Warning("Ignoring SSL verification is very unsafe")
}

View File

@@ -103,17 +103,17 @@ func Bool(b *bool, name string) {
}
func ImageTypes(it *[]imagetype.Type, name string) error {
*it = []imagetype.Type{}
if env := os.Getenv(name); len(env) > 0 {
parts := strings.Split(env, ",")
*it = make([]imagetype.Type, 0, len(parts))
for _, p := range parts {
pt := strings.TrimSpace(p)
if t, ok := imagetype.Types[pt]; ok {
*it = append(*it, t)
} else {
return fmt.Errorf("Unknown image format to skip: %s", pt)
return fmt.Errorf("Unknown image format: %s", pt)
}
}
}

View File

@@ -249,6 +249,22 @@ You can set up a fallback image that will be used in case imgproxy is unable to
* `IMGPROXY_FALLBACK_IMAGE_TTL`: a duration (in seconds) sent via the `Expires` and `Cache-Control: max-age` HTTP headers when a fallback image was used. When blank or `0`, the value from `IMGPROXY_TTL` is used.
* `IMGPROXY_FALLBACK_IMAGES_CACHE_SIZE`: ![pro](/assets/pro.svg) the size of custom fallback images cache. When set to `0`, the fallback image cache is disabled. 256 fallback images are cached by default.
## Preferred formats
When the resulting image format is not explicitly specified in the imgproxy URL via the extension or the `format` processing option, imgproxy will choose one of the preferred formats as the resultant:
* `IMGPROXY_PREFERRED_FORMATS`: a list of preferred formats, comma divided. Default: `jpeg,png,gif,webp,avif,ico`
imgproxy is guided by the following rules when choosing the resulting format:
1. If the preferred formats list contains the source image format, it will be used as the resultant
2. If the resulting image is animated, the resulting image format should support animations
3. If the resulting image contains transparency, the resulting image format should support transparency
4. imgproxy chooses the first preferred format that meets those requirements
5. If none of the preferred formats meet the requirements, the first preferred format is used as the resultant
**📝Note:** When AVIF/WebP support detection is enabled and the browser supports AVIF/WebP, it may be used as the resultant format even if the preferred formats list doesn't contain it.
## Skip processing
You can configure imgproxy to skip processing of some formats:

View File

@@ -20,6 +20,7 @@ import (
"github.com/imgproxy/imgproxy/v3/metrics"
"github.com/imgproxy/imgproxy/v3/metrics/prometheus"
"github.com/imgproxy/imgproxy/v3/options"
"github.com/imgproxy/imgproxy/v3/processing"
"github.com/imgproxy/imgproxy/v3/version"
"github.com/imgproxy/imgproxy/v3/vips"
)
@@ -51,6 +52,11 @@ func initialize() error {
return err
}
if err := processing.ValidatePreferredFormats(); err != nil {
vips.Shutdown()
return err
}
if err := options.ParsePresets(config.Presets); err != nil {
vips.Shutdown()
return err

View File

@@ -37,9 +37,40 @@ var mainPipeline = pipeline{
finalize,
}
func imageTypeGoodForWeb(imgtype imagetype.Type) bool {
return imgtype != imagetype.TIFF &&
imgtype != imagetype.BMP
func isImageTypePreferred(imgtype imagetype.Type) bool {
for _, t := range config.PreferredFormats {
if imgtype == t {
return true
}
}
return false
}
func findBestFormat(srcType imagetype.Type, animated, expectAlpha bool) imagetype.Type {
for _, t := range config.PreferredFormats {
if animated && !t.SupportsAnimation() {
continue
}
if expectAlpha && !t.SupportsAlpha() {
continue
}
return t
}
return config.PreferredFormats[0]
}
func ValidatePreferredFormats() error {
for _, t := range config.PreferredFormats {
if !vips.SupportsSave(t) {
return fmt.Errorf("%s can't be a preferred format as it's saving is not supported", t)
}
}
return nil
}
func canFitToBytes(imgtype imagetype.Type) bool {
@@ -223,6 +254,7 @@ func ProcessImage(ctx context.Context, imgdata *imagedata.ImageData, po *options
originWidth, originHeight := getImageSize(img)
animated := img.IsAnimated()
expectAlpha := !po.Flatten && (img.HasAlpha() || po.Padding.Enabled || po.Extend.Enabled)
switch {
case po.Format == imagetype.Unknown:
@@ -231,10 +263,10 @@ func ProcessImage(ctx context.Context, imgdata *imagedata.ImageData, po *options
po.Format = imagetype.AVIF
case po.PreferWebP:
po.Format = imagetype.WEBP
case vips.SupportsSave(imgdata.Type) && imageTypeGoodForWeb(imgdata.Type):
case isImageTypePreferred(imgdata.Type):
po.Format = imgdata.Type
default:
po.Format = imagetype.JPEG
po.Format = findBestFormat(imgdata.Type, animated, expectAlpha)
}
case po.EnforceAvif && !animated:
po.Format = imagetype.AVIF