DarthSim 6 лет назад
Родитель
Сommit
5040ba7d61
5 измененных файлов с 76 добавлено и 12 удалено
  1. 17 6
      docs/generating_the_url_advanced.md
  2. 23 0
      process.go
  3. 24 3
      processing_options.go
  4. 10 3
      vips.c
  5. 2 0
      vips.h

+ 17 - 6
docs/generating_the_url_advanced.md

@@ -34,20 +34,20 @@ imgproxy supports the following processing options:
 ##### Resize
 
 ```
-resize:%resizing_type:%width:%height:%enlarge
-rs:%resizing_type:%width:%height:%enlarge
+resize:%resizing_type:%width:%height:%enlarge:%extend
+rs:%resizing_type:%width:%height:%enlarge:%extend
 ```
 
-Meta-option that defines the [resizing type](#resizing-type), [width](#width), [height](#height), and [enlarge](#enlarge). All arguments are optional and can be omited to use their default values.
+Meta-option that defines the [resizing type](#resizing-type), [width](#width), [height](#height), [enlarge](#enlarge), and [extend](#extend). All arguments are optional and can be omited to use their default values.
 
 ##### Size
 
 ```
-size:%width:%height:%enlarge
-s:%width:%height:%enlarge
+size:%width:%height:%enlarge:%extend
+s:%width:%height:%enlarge:%extend
 ```
 
-Meta-option that defines the [width](#width), [height](#height), and [enlarge](#enlarge). All arguments are optional and can be omited to use their default values.
+Meta-option that defines the [width](#width), [height](#height), [enlarge](#enlarge), and [extend](#extend). All arguments are optional and can be omited to use their default values.
 
 ##### Resizing type
 
@@ -107,6 +107,17 @@ If set to `0`, imgproxy will not enlarge the image if it is smaller than the giv
 
 Default: `0`
 
+##### Extend
+
+```
+extend:%extend
+ex:%extend
+```
+
+If set to `0`, imgproxy will not extend the image if the resizing result is smaller than the given size. With any other value, imgproxy will extend the image to the given size.
+
+Default: `0`
+
 ##### Gravity
 
 ```

+ 23 - 0
process.go

@@ -389,6 +389,18 @@ func transformImage(ctx context.Context, img **C.VipsImage, data []byte, po *pro
 		}
 	}
 
+	if po.Expand && (po.Width > int((*img).Xsize) || po.Height > int((*img).Ysize)) {
+		if err = vipsEnsureAlpha(img); err != nil {
+			return err
+		}
+
+		hasAlpha = true
+
+		if err = vipsEmbed(img, gravityCenter, C.int(po.Width), C.int(po.Height), 0, 0); err != nil {
+			return err
+		}
+	}
+
 	if hasAlpha && (po.Flatten || po.Format == imageTypeJPEG) {
 		if err = vipsFlatten(img, po.Background); err != nil {
 			return err
@@ -769,6 +781,17 @@ func vipsSmartCrop(img **C.VipsImage, width, height int) error {
 	return nil
 }
 
+func vipsEnsureAlpha(img **C.VipsImage) error {
+	var tmp *C.VipsImage
+
+	if C.vips_ensure_alpha(*img, &tmp) != 0 {
+		return vipsError()
+	}
+
+	C.swap_and_clear(img, tmp)
+	return nil
+}
+
 func vipsFlatten(img **C.VipsImage, bg rgbColor) error {
 	var tmp *C.VipsImage
 

+ 24 - 3
processing_options.go

@@ -124,6 +124,7 @@ type processingOptions struct {
 	Dpr        float64
 	Gravity    gravityOptions
 	Enlarge    bool
+	Expand     bool
 	Format     imageType
 	Quality    int
 	Flatten    bool
@@ -322,8 +323,18 @@ func applyEnlargeOption(po *processingOptions, args []string) error {
 	return nil
 }
 
+func applyExtendOption(po *processingOptions, args []string) error {
+	if len(args) > 1 {
+		return fmt.Errorf("Invalid expand arguments: %v", args)
+	}
+
+	po.Expand = args[0] != "0"
+
+	return nil
+}
+
 func applySizeOption(po *processingOptions, args []string) (err error) {
-	if len(args) > 3 {
+	if len(args) > 4 {
 		return fmt.Errorf("Invalid size arguments: %v", args)
 	}
 
@@ -339,12 +350,18 @@ func applySizeOption(po *processingOptions, args []string) (err error) {
 		}
 	}
 
-	if len(args) == 3 && len(args[2]) > 0 {
+	if len(args) >= 3 && len(args[2]) > 0 {
 		if err = applyEnlargeOption(po, args[2:3]); err != nil {
 			return
 		}
 	}
 
+	if len(args) == 4 && len(args[3]) > 0 {
+		if err = applyExtendOption(po, args[3:4]); err != nil {
+			return
+		}
+	}
+
 	return nil
 }
 
@@ -363,7 +380,7 @@ func applyResizingTypeOption(po *processingOptions, args []string) error {
 }
 
 func applyResizeOption(po *processingOptions, args []string) error {
-	if len(args) > 4 {
+	if len(args) > 5 {
 		return fmt.Errorf("Invalid resize arguments: %v", args)
 	}
 
@@ -640,6 +657,10 @@ func applyProcessingOption(po *processingOptions, name string, args []string) er
 		if err := applyEnlargeOption(po, args); err != nil {
 			return err
 		}
+	case "extend", "ex":
+		if err := applyExtendOption(po, args); err != nil {
+			return err
+		}
 	case "dpr":
 		if err := applyDprOption(po, args); err != nil {
 			return err

+ 10 - 3
vips.c

@@ -288,10 +288,17 @@ vips_embed_go(VipsImage *in, VipsImage **out, int x, int y, int width, int heigh
 }
 
 int
-vips_apply_opacity(VipsImage *in, VipsImage **out, double opacity){
-  gboolean has_alpha = vips_image_hasalpha_go(in);
+vips_ensure_alpha(VipsImage *in, VipsImage **out) {
+  if (vips_image_hasalpha_go(in)) {
+    return vips_copy(in, out, NULL);
+  }
 
-  if (has_alpha) {
+  return vips_bandjoin_const1(in, out, 255, NULL);
+}
+
+int
+vips_apply_opacity(VipsImage *in, VipsImage **out, double opacity){
+  if (vips_image_hasalpha_go(in)) {
     if (opacity < 1) {
       VipsImage *img, *img_alpha, *tmp;
 

+ 2 - 0
vips.h

@@ -63,7 +63,9 @@ int vips_flatten_go(VipsImage *in, VipsImage **out, double r, double g, double b
 int vips_replicate_go(VipsImage *in, VipsImage **out, int across, int down);
 int vips_embed_go(VipsImage *in, VipsImage **out, int x, int y, int width, int height);
 
+int vips_ensure_alpha(VipsImage *in, VipsImage **out);
 int vips_apply_opacity(VipsImage *in, VipsImage **out, double opacity);
+
 int vips_apply_watermark(VipsImage *in, VipsImage *watermark, VipsImage **out, double opacity);
 
 int vips_arrayjoin_go(VipsImage **in, VipsImage **out, int n);