Browse Source

Merge branch 'version/3' of github.com:imgproxy/imgproxy into version/3

DarthSim 4 years ago
parent
commit
36f318f390
6 changed files with 88 additions and 1 deletions
  1. 1 1
      docs/generating_the_url.md
  2. 7 0
      process.go
  3. 17 0
      processing_options.go
  4. 49 0
      vips.c
  5. 12 0
      vips.go
  6. 2 0
      vips.h

+ 1 - 1
docs/generating_the_url.md

@@ -350,7 +350,7 @@ As an approximate guideline, use 0.5 sigma for 4 pixels/mm (display resolution),
 
 Default: disabled
 
-### Pixelate<img class='pro-badge' src='assets/pro.svg' alt='pro' /> :id=pixelate
+### Pixelate
 
 ```
 pixelate:%size

+ 7 - 0
process.go

@@ -571,6 +571,13 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
 		}
 	}
 
+	if po.Pixelate > 1 {
+		pixels := minInt(po.Pixelate, minInt(img.Width(), img.Height()))
+		if err = img.Pixelate(pixels); err != nil {
+			return err
+		}
+	}
+
 	if err = copyMemoryAndCheckTimeout(ctx, img); err != nil {
 		return err
 	}

+ 17 - 0
processing_options.go

@@ -149,6 +149,7 @@ type processingOptions struct {
 	Background        rgbColor
 	Blur              float32
 	Sharpen           float32
+	Pixelate          int
 	StripMetadata     bool
 	StripColorProfile bool
 	AutoRotate        bool
@@ -807,6 +808,20 @@ func applySharpenOption(po *processingOptions, args []string) error {
 	return nil
 }
 
+func applyPixelateOption(po *processingOptions, args []string) error {
+	if len(args) > 1 {
+		return fmt.Errorf("Invalid pixelate arguments: %v", args)
+	}
+
+	if p, err := strconv.Atoi(args[0]); err == nil && p >= 0 {
+		po.Pixelate = p
+	} else {
+		return fmt.Errorf("Invalid pixelate: %s", args[0])
+	}
+
+	return nil
+}
+
 func applyPresetOption(po *processingOptions, args []string) error {
 	for _, preset := range args {
 		if p, ok := conf.Presets[preset]; ok {
@@ -1014,6 +1029,8 @@ func applyProcessingOption(po *processingOptions, name string, args []string) er
 		return applyBlurOption(po, args)
 	case "sharpen", "sh":
 		return applySharpenOption(po, args)
+	case "pixelate", "pix":
+		return applyPixelateOption(po, args)
 	case "watermark", "wm":
 		return applyWatermarkOption(po, args)
 	case "strip_metadata", "sm":

+ 49 - 0
vips.c

@@ -267,6 +267,55 @@ vips_resize_with_premultiply(VipsImage *in, VipsImage **out, double wscale, doub
   return 0;
 }
 
+int
+vips_pixelate(VipsImage *in, VipsImage **out, int pixels) {
+  VipsImage *base = vips_image_new();
+  VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 3);
+
+  int w, h, tw, th;
+
+  w = in->Xsize;
+  h = in->Ysize;
+
+  tw = (int)((double)(w + pixels - 1) / pixels) * pixels;
+  th = (int)((double)(h + pixels - 1) / pixels) * pixels;
+
+  if (tw > w || th > h) {
+    if (vips_embed(in, &t[0], 0, 0, tw, th, "extend", VIPS_EXTEND_COPY, NULL)) {
+      clear_image(&base);
+      return 1;
+    }
+  } else {
+    if (vips_copy(in, &t[0], NULL)) {
+      clear_image(&base);
+      return 1;
+    }
+  }
+
+  if (
+    vips_shrink(t[0], &t[1], pixels, pixels, NULL) ||
+    vips_zoom(t[1], &t[2], pixels, pixels, NULL)
+  ) {
+      clear_image(&base);
+      return 1;
+  }
+
+  if (tw > w || th > h) {
+    if (vips_extract_area(t[2], out, 0, 0, w, h, NULL)) {
+        clear_image(&base);
+        return 1;
+    }
+  } else {
+    if (vips_copy(t[2], out, NULL)) {
+        clear_image(&base);
+        return 1;
+    }
+  }
+
+  clear_image(&base);
+  return 0;
+}
+
 int
 vips_icc_is_srgb_iec61966(VipsImage *in) {
   const void *data;

+ 12 - 0
vips.go

@@ -422,6 +422,18 @@ func (img *vipsImage) Resize(wscale, hscale float64, hasAlpa bool) error {
 	return nil
 }
 
+func (img *vipsImage) Pixelate(pixels int) error {
+	var tmp *C.VipsImage
+
+	if C.vips_pixelate(img.VipsImage, &tmp, C.int(pixels)) != 0 {
+		return vipsError()
+	}
+
+	C.swap_and_clear(&img.VipsImage, tmp)
+
+	return nil
+}
+
 func (img *vipsImage) Orientation() C.int {
 	return C.vips_get_orientation(img.VipsImage)
 }

+ 2 - 0
vips.h

@@ -58,6 +58,8 @@ int vips_rad2float_go(VipsImage *in, VipsImage **out);
 int vips_resize_go(VipsImage *in, VipsImage **out, double wscale, double hscale);
 int vips_resize_with_premultiply(VipsImage *in, VipsImage **out, double wscale, double hscale);
 
+int vips_pixelate(VipsImage *in, VipsImage **out, int pixels);
+
 int vips_icc_is_srgb_iec61966(VipsImage *in);
 int vips_has_embedded_icc(VipsImage *in);
 int vips_icc_import_go(VipsImage *in, VipsImage **out);