Browse Source

fill-down resiziong type

DarthSim 4 years ago
parent
commit
59f5dac4bd
4 changed files with 30 additions and 13 deletions
  1. 1 1
      CHANGELOG.md
  2. 1 0
      docs/generating_the_url.md
  3. 22 8
      process.go
  4. 6 4
      processing_options.go

+ 1 - 1
CHANGELOG.md

@@ -6,7 +6,7 @@
 - [expires](https://docs.imgproxy.net/#/generating_the_url?id=expires) processing option.
 - [expires](https://docs.imgproxy.net/#/generating_the_url?id=expires) processing option.
 - [skip processing](https://docs.imgproxy.net/#/generating_the_url?id=skip-processing) processing option.
 - [skip processing](https://docs.imgproxy.net/#/generating_the_url?id=skip-processing) processing option.
 - [Datadog](./docs/datadog.md) metrics.
 - [Datadog](./docs/datadog.md) metrics.
-- `force` resizing type.
+- `force` and `fill-down` resizing types.
 
 
 ### 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.

+ 1 - 0
docs/generating_the_url.md

@@ -56,6 +56,7 @@ Defines how imgproxy will resize the source image. Supported resizing types are:
 
 
 * `fit`: resizes the image while keeping aspect ratio to fit given size;
 * `fit`: resizes the image while keeping aspect ratio to fit given size;
 * `fill`: resizes the image while keeping aspect ratio to fill given size and cropping projecting parts;
 * `fill`: resizes the image while keeping aspect ratio to fill given size and cropping projecting parts;
+* `fill-down`: same as `fill`, but if the resized image is smaller than the requested size, imgproxy will crop the result to keep the requested aspect ratio;
 * `force`: resizes the image without keeping aspect ratio;
 * `force`: resizes the image without keeping aspect ratio;
 * `auto`: if both source and resulting dimensions have the same orientation (portrait or landscape), imgproxy will use `fill`. Otherwise, it will use `fit`.
 * `auto`: if both source and resulting dimensions have the same orientation (portrait or landscape), imgproxy will use `fill`. Otherwise, it will use `fit`.
 
 

+ 22 - 8
process.go

@@ -118,7 +118,7 @@ func calcScale(width, height int, po *processingOptions, imgtype imageType) (flo
 		case rt == resizeFit:
 		case rt == resizeFit:
 			wshrink = math.Max(wshrink, hshrink)
 			wshrink = math.Max(wshrink, hshrink)
 			hshrink = wshrink
 			hshrink = wshrink
-		case rt == resizeFill:
+		case rt == resizeFill || rt == resizeFillDown:
 			wshrink = math.Min(wshrink, hshrink)
 			wshrink = math.Min(wshrink, hshrink)
 			hshrink = wshrink
 			hshrink = wshrink
 		}
 		}
@@ -459,13 +459,27 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
 		return err
 		return err
 	}
 	}
 
 
-	dprWidth := scaleInt(po.Width, po.Dpr)
-	dprHeight := scaleInt(po.Height, po.Dpr)
-
 	if err = cropImage(img, cropWidth, cropHeight, &cropGravity); err != nil {
 	if err = cropImage(img, cropWidth, cropHeight, &cropGravity); err != nil {
 		return err
 		return err
 	}
 	}
-	if err = cropImage(img, dprWidth, dprHeight, &po.Gravity); err != nil {
+
+	// Crop image to the result size
+	resultWidth := scaleInt(po.Width, po.Dpr)
+	resultHeight := scaleInt(po.Height, po.Dpr)
+
+	if po.ResizingType == resizeFillDown {
+		if resultWidth > img.Width() {
+			resultHeight = scaleInt(resultHeight, float64(img.Width())/float64(resultWidth))
+			resultWidth = img.Width()
+		}
+
+		if resultHeight > img.Height() {
+			resultWidth = scaleInt(resultWidth, float64(img.Height())/float64(resultHeight))
+			resultHeight = img.Height()
+		}
+	}
+
+	if err = cropImage(img, resultWidth, resultHeight, &po.Gravity); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -547,9 +561,9 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
 		return err
 		return err
 	}
 	}
 
 
-	if po.Extend.Enabled && (dprWidth > img.Width() || dprHeight > img.Height()) {
-		offX, offY := calcPosition(dprWidth, dprHeight, img.Width(), img.Height(), &po.Extend.Gravity, false)
-		if err = img.Embed(dprWidth, dprHeight, offX, offY, po.Background, transparentBg); err != nil {
+	if po.Extend.Enabled && (resultWidth > img.Width() || resultHeight > img.Height()) {
+		offX, offY := calcPosition(resultWidth, resultHeight, img.Width(), img.Height(), &po.Extend.Gravity, false)
+		if err = img.Embed(resultWidth, resultHeight, offX, offY, po.Background, transparentBg); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}

+ 6 - 4
processing_options.go

@@ -65,15 +65,17 @@ type resizeType int
 const (
 const (
 	resizeFit resizeType = iota
 	resizeFit resizeType = iota
 	resizeFill
 	resizeFill
+	resizeFillDown
 	resizeForce
 	resizeForce
 	resizeAuto
 	resizeAuto
 )
 )
 
 
 var resizeTypes = map[string]resizeType{
 var resizeTypes = map[string]resizeType{
-	"fit":   resizeFit,
-	"fill":  resizeFill,
-	"force": resizeForce,
-	"auto":  resizeAuto,
+	"fit":       resizeFit,
+	"fill":      resizeFill,
+	"fill-down": resizeFillDown,
+	"force":     resizeForce,
+	"auto":      resizeAuto,
 }
 }
 
 
 type rgbColor struct{ R, G, B uint8 }
 type rgbColor struct{ R, G, B uint8 }