Kaynağa Gözat

Add zoom option

DarthSim 3 yıl önce
ebeveyn
işleme
fff164f45a

+ 1 - 0
CHANGELOG.md

@@ -3,6 +3,7 @@
 ## [Unreleased]
 ## [Unreleased]
 ### Added
 ### Added
 - (pro) Add `video_meta` to the `/info` response.
 - (pro) Add `video_meta` to the `/info` response.
+- Add [zoom](https://docs.imgproxy.net/generating_the_url?id=zoom) processing option.
 - Add 1/2/4-bit BMP support.
 - Add 1/2/4-bit BMP support.
 
 
 ### Change
 ### Change

+ 20 - 0
docs/generating_the_url.md

@@ -121,6 +121,24 @@ Defines the minimum height of the resulting image.
 
 
 Default: `0`
 Default: `0`
 
 
+### Zoom
+
+```
+zoom:%zoom_x_y
+z:%zoom_x_y
+
+zoom:%zoom_x %zoom_y
+z:%zoom_x %zoom_y
+```
+
+When set, imgproxy will multiply the image dimensions according to these factors. The values must be greater than 0.
+
+Can be combined with `width` and `height` options. In this case, imgproxy calculates scale factors for the provided size and then multiplies it with the provided zoom factors.
+
+**📝Note:** Unlike [dpr](#dpr), `zoom` doesn't set `Content-DPR` header in the response.
+
+Default: `1`
+
 ### Dpr
 ### Dpr
 
 
 ```
 ```
@@ -129,6 +147,8 @@ dpr:%dpr
 
 
 When set, imgproxy will multiply the image dimensions according to this factor for HiDPI (Retina) devices. The value must be greater than 0.
 When set, imgproxy will multiply the image dimensions according to this factor for HiDPI (Retina) devices. The value must be greater than 0.
 
 
+**📝Note:** `dpr` also sets `Content-DPR` header in the response so the browser can render the image correctly.
+
 Default: `1`
 Default: `1`
 
 
 ### Enlarge
 ### Enlarge

+ 31 - 0
options/processing_options.go

@@ -65,6 +65,8 @@ type ProcessingOptions struct {
 	Height            int
 	Height            int
 	MinWidth          int
 	MinWidth          int
 	MinHeight         int
 	MinHeight         int
+	ZoomWidth         float64
+	ZoomHeight        float64
 	Dpr               float64
 	Dpr               float64
 	Gravity           GravityOptions
 	Gravity           GravityOptions
 	Enlarge           bool
 	Enlarge           bool
@@ -115,6 +117,8 @@ func NewProcessingOptions() *ProcessingOptions {
 			ResizingType:      ResizeFit,
 			ResizingType:      ResizeFit,
 			Width:             0,
 			Width:             0,
 			Height:            0,
 			Height:            0,
+			ZoomWidth:         1,
+			ZoomHeight:        1,
 			Gravity:           GravityOptions{Type: GravityCenter},
 			Gravity:           GravityOptions{Type: GravityCenter},
 			Enlarge:           false,
 			Enlarge:           false,
 			Extend:            ExtendOptions{Enabled: false, Gravity: GravityOptions{Type: GravityCenter}},
 			Extend:            ExtendOptions{Enabled: false, Gravity: GravityOptions{Type: GravityCenter}},
@@ -375,6 +379,31 @@ func applyResizeOption(po *ProcessingOptions, args []string) error {
 	return nil
 	return nil
 }
 }
 
 
+func applyZoomOption(po *ProcessingOptions, args []string) error {
+	nArgs := len(args)
+
+	if nArgs > 2 {
+		return fmt.Errorf("Invalid zoom arguments: %v", args)
+	}
+
+	if z, err := strconv.ParseFloat(args[0], 64); err == nil && z > 0 {
+		po.ZoomWidth = z
+		po.ZoomHeight = z
+	} else {
+		return fmt.Errorf("Invalid zoom value: %s", args[0])
+	}
+
+	if nArgs > 1 {
+		if z, err := strconv.ParseFloat(args[1], 64); err == nil && z > 0 {
+			po.ZoomHeight = z
+		} else {
+			return fmt.Errorf("Invalid zoom value: %s", args[0])
+		}
+	}
+
+	return nil
+}
+
 func applyDprOption(po *ProcessingOptions, args []string) error {
 func applyDprOption(po *ProcessingOptions, args []string) error {
 	if len(args) > 1 {
 	if len(args) > 1 {
 		return fmt.Errorf("Invalid dpr arguments: %v", args)
 		return fmt.Errorf("Invalid dpr arguments: %v", args)
@@ -822,6 +851,8 @@ func applyURLOption(po *ProcessingOptions, name string, args []string) error {
 		return applyMinWidthOption(po, args)
 		return applyMinWidthOption(po, args)
 	case "min-height", "mh":
 	case "min-height", "mh":
 		return applyMinHeightOption(po, args)
 		return applyMinHeightOption(po, args)
+	case "zoom", "z":
+		return applyZoomOption(po, args)
 	case "dpr":
 	case "dpr":
 		return applyDprOption(po, args)
 		return applyDprOption(po, args)
 	case "enlarge", "el":
 	case "enlarge", "el":

+ 1 - 2
processing/crop.go

@@ -53,8 +53,7 @@ func crop(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions,
 
 
 func cropToResult(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions, imgdata *imagedata.ImageData) error {
 func cropToResult(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions, imgdata *imagedata.ImageData) error {
 	// Crop image to the result size
 	// Crop image to the result size
-	resultWidth := imath.Scale(po.Width, po.Dpr)
-	resultHeight := imath.Scale(po.Height, po.Dpr)
+	resultWidth, resultHeight := resultSize(po)
 
 
 	if po.ResizingType == options.ResizeFillDown {
 	if po.ResizingType == options.ResizeFillDown {
 		if resultWidth > img.Width() {
 		if resultWidth > img.Width() {

+ 1 - 3
processing/extend.go

@@ -2,14 +2,12 @@ package processing
 
 
 import (
 import (
 	"github.com/imgproxy/imgproxy/v3/imagedata"
 	"github.com/imgproxy/imgproxy/v3/imagedata"
-	"github.com/imgproxy/imgproxy/v3/imath"
 	"github.com/imgproxy/imgproxy/v3/options"
 	"github.com/imgproxy/imgproxy/v3/options"
 	"github.com/imgproxy/imgproxy/v3/vips"
 	"github.com/imgproxy/imgproxy/v3/vips"
 )
 )
 
 
 func extend(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions, imgdata *imagedata.ImageData) error {
 func extend(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions, imgdata *imagedata.ImageData) error {
-	resultWidth := imath.Scale(po.Width, po.Dpr)
-	resultHeight := imath.Scale(po.Height, po.Dpr)
+	resultWidth, resultHeight := resultSize(po)
 
 
 	if !po.Extend.Enabled || (resultWidth <= img.Width() && resultHeight <= img.Height()) {
 	if !po.Extend.Enabled || (resultWidth <= img.Width() && resultHeight <= img.Height()) {
 		return nil
 		return nil

+ 3 - 0
processing/prepare.go

@@ -98,6 +98,9 @@ func calcScale(width, height int, po *options.ProcessingOptions, imgtype imagety
 		}
 		}
 	}
 	}
 
 
+	wshrink /= po.ZoomWidth
+	hshrink /= po.ZoomHeight
+
 	if !po.Enlarge && imgtype != imagetype.SVG {
 	if !po.Enlarge && imgtype != imagetype.SVG {
 		if wshrink < 1 {
 		if wshrink < 1 {
 			hshrink /= wshrink
 			hshrink /= wshrink

+ 13 - 0
processing/result_size.go

@@ -0,0 +1,13 @@
+package processing
+
+import (
+	"github.com/imgproxy/imgproxy/v3/imath"
+	"github.com/imgproxy/imgproxy/v3/options"
+)
+
+func resultSize(po *options.ProcessingOptions) (int, int) {
+	resultWidth := imath.Scale(po.Width, po.Dpr*po.ZoomWidth)
+	resultHeight := imath.Scale(po.Height, po.Dpr*po.ZoomHeight)
+
+	return resultWidth, resultHeight
+}