mirror of
				https://github.com/imgproxy/imgproxy.git
				synced 2025-10-30 23:08:02 +02:00 
			
		
		
		
	Make filters low-level
This commit is contained in:
		| @@ -2,7 +2,6 @@ package processing | ||||
|  | ||||
| import ( | ||||
| 	"github.com/imgproxy/imgproxy/v3/imagedata" | ||||
| 	"github.com/imgproxy/imgproxy/v3/imath" | ||||
| 	"github.com/imgproxy/imgproxy/v3/options" | ||||
| 	"github.com/imgproxy/imgproxy/v3/vips" | ||||
| ) | ||||
| @@ -20,35 +19,7 @@ func applyFilters(pctx *pipelineContext, img *vips.Image, po *options.Processing | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// When image has alpha, we need to premultiply it to get rid of black edges | ||||
| 	if err := img.Premultiply(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if po.Blur > 0 { | ||||
| 		if err := img.Blur(po.Blur); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if po.Sharpen > 0 { | ||||
| 		if err := img.Sharpen(po.Sharpen); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if po.Pixelate > 1 { | ||||
| 		pixels := imath.Min(po.Pixelate, imath.Min(img.Width(), img.Height())) | ||||
| 		if err := img.Pixelate(pixels); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if err := img.Unpremultiply(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := img.CastUchar(); err != nil { | ||||
| 	if err := img.ApplyFilters(po.Blur, po.Sharpen, po.Pixelate); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										164
									
								
								vips/vips.c
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								vips/vips.c
									
									
									
									
									
								
							| @@ -177,22 +177,6 @@ vips_addalpha_go(VipsImage *in, VipsImage **out) { | ||||
|   return vips_addalpha(in, out, NULL); | ||||
| } | ||||
|  | ||||
| int | ||||
| vips_premultiply_go(VipsImage *in, VipsImage **out) { | ||||
|   if (!vips_image_hasalpha(in)) | ||||
|     return vips_copy(in, out, NULL); | ||||
|  | ||||
|   return vips_premultiply(in, out, NULL); | ||||
| } | ||||
|  | ||||
| int | ||||
| vips_unpremultiply_go(VipsImage *in, VipsImage **out) { | ||||
|   if (!vips_image_hasalpha(in)) | ||||
|     return vips_copy(in, out, NULL); | ||||
|  | ||||
|   return vips_unpremultiply(in, out, NULL); | ||||
| } | ||||
|  | ||||
| int | ||||
| vips_copy_go(VipsImage *in, VipsImage **out) { | ||||
|   return vips_copy(in, out, NULL); | ||||
| @@ -229,55 +213,6 @@ vips_resize_go(VipsImage *in, VipsImage **out, double wscale, double hscale) { | ||||
|   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; | ||||
| @@ -364,13 +299,100 @@ vips_smartcrop_go(VipsImage *in, VipsImage **out, int width, int height) { | ||||
| } | ||||
|  | ||||
| int | ||||
| vips_gaussblur_go(VipsImage *in, VipsImage **out, double sigma) { | ||||
|   return vips_gaussblur(in, out, sigma, NULL); | ||||
| } | ||||
| vips_apply_filters(VipsImage *in, VipsImage **out, double blur_sigma, | ||||
|   double sharp_sigma, int pixelate_pixels) { | ||||
|  | ||||
| int | ||||
| vips_sharpen_go(VipsImage *in, VipsImage **out, double sigma) { | ||||
|   return vips_sharpen(in, out, "sigma", sigma, NULL); | ||||
|   VipsImage *base = vips_image_new(); | ||||
|   VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 9); | ||||
|  | ||||
|   VipsInterpretation interpretation = in->Type; | ||||
|   VipsBandFormat format = in->BandFmt; | ||||
|   gboolean premultiplied = FALSE; | ||||
|  | ||||
|   if ((blur_sigma > 0 || sharp_sigma > 0) && vips_image_hasalpha(in)) { | ||||
|     if (vips_premultiply(in, &t[0], NULL)) { | ||||
|       clear_image(&base); | ||||
|       return 1; | ||||
|     } | ||||
|  | ||||
|     in = t[0]; | ||||
|     premultiplied = TRUE; | ||||
|   } | ||||
|  | ||||
|   if (blur_sigma > 0.0) { | ||||
|     if (vips_gaussblur(in, &t[1], blur_sigma, NULL)) { | ||||
|       clear_image(&base); | ||||
|       return 1; | ||||
|     } | ||||
|  | ||||
|     in = t[1]; | ||||
|   } | ||||
|  | ||||
|   if (sharp_sigma > 0.0) { | ||||
|     if (vips_sharpen(in, &t[2], "sigma", sharp_sigma, NULL)) { | ||||
|       clear_image(&base); | ||||
|       return 1; | ||||
|     } | ||||
|  | ||||
|     in = t[2]; | ||||
|   } | ||||
|  | ||||
|   pixelate_pixels = VIPS_MIN(pixelate_pixels, VIPS_MAX(in->Xsize, in->Ysize)); | ||||
|  | ||||
|   if (pixelate_pixels > 1) { | ||||
|     int w, h, tw, th; | ||||
|  | ||||
|     w = in->Xsize; | ||||
|     h = in->Ysize; | ||||
|  | ||||
|     tw = (int)(VIPS_CEIL((double)w / pixelate_pixels)) * pixelate_pixels; | ||||
|     th = (int)(VIPS_CEIL((double)h / pixelate_pixels)) * pixelate_pixels; | ||||
|  | ||||
|     if (tw > w || th > h) { | ||||
|       if (vips_embed(in, &t[3], 0, 0, tw, th, "extend", VIPS_EXTEND_MIRROR, NULL)) { | ||||
|         clear_image(&base); | ||||
|         return 1; | ||||
|       } | ||||
|  | ||||
|       in = t[3]; | ||||
|     } | ||||
|  | ||||
|     if ( | ||||
|       vips_shrink(in, &t[4], pixelate_pixels, pixelate_pixels, NULL) || | ||||
|       vips_zoom(t[4], &t[5], pixelate_pixels, pixelate_pixels, NULL) | ||||
|     ) { | ||||
|         clear_image(&base); | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
|     in = t[5]; | ||||
|  | ||||
|     if (tw > w || th > h) { | ||||
|       if (vips_extract_area(in, &t[6], 0, 0, w, h, NULL)) { | ||||
|           clear_image(&base); | ||||
|           return 1; | ||||
|       } | ||||
|  | ||||
|       in = t[6]; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (premultiplied) { | ||||
|     if (vips_unpremultiply(in, &t[7], NULL)) { | ||||
|       clear_image(&base); | ||||
|       return 1; | ||||
|     } | ||||
|  | ||||
|     in = t[7]; | ||||
|   } | ||||
|  | ||||
|   int res = | ||||
|     vips_colourspace(in, &t[8], interpretation, NULL) || | ||||
|     vips_cast(t[8], out, format, NULL); | ||||
|  | ||||
|   clear_image(&base); | ||||
|  | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| int | ||||
|   | ||||
							
								
								
									
										48
									
								
								vips/vips.go
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								vips/vips.go
									
									
									
									
									
								
							| @@ -363,28 +363,6 @@ func (img *Image) HasAlpha() bool { | ||||
| 	return C.vips_image_hasalpha(img.VipsImage) > 0 | ||||
| } | ||||
|  | ||||
| func (img *Image) Premultiply() error { | ||||
| 	var tmp *C.VipsImage | ||||
|  | ||||
| 	if C.vips_premultiply_go(img.VipsImage, &tmp) != 0 { | ||||
| 		return Error() | ||||
| 	} | ||||
|  | ||||
| 	C.swap_and_clear(&img.VipsImage, tmp) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (img *Image) Unpremultiply() error { | ||||
| 	var tmp *C.VipsImage | ||||
|  | ||||
| 	if C.vips_unpremultiply_go(img.VipsImage, &tmp) != 0 { | ||||
| 		return Error() | ||||
| 	} | ||||
|  | ||||
| 	C.swap_and_clear(&img.VipsImage, tmp) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (img *Image) GetInt(name string) (int, error) { | ||||
| 	var i C.int | ||||
|  | ||||
| @@ -499,18 +477,6 @@ func (img *Image) Resize(wscale, hscale float64) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (img *Image) Pixelate(pixels int) error { | ||||
| 	var tmp *C.VipsImage | ||||
|  | ||||
| 	if C.vips_pixelate(img.VipsImage, &tmp, C.int(pixels)) != 0 { | ||||
| 		return Error() | ||||
| 	} | ||||
|  | ||||
| 	C.swap_and_clear(&img.VipsImage, tmp) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (img *Image) Orientation() C.int { | ||||
| 	return C.vips_get_orientation(img.VipsImage) | ||||
| } | ||||
| @@ -609,25 +575,15 @@ func (img *Image) Flatten(bg Color) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (img *Image) Blur(sigma float32) error { | ||||
| func (img *Image) ApplyFilters(blurSigma, sharpSigma float32, pixelatePixels int) error { | ||||
| 	var tmp *C.VipsImage | ||||
|  | ||||
| 	if C.vips_gaussblur_go(img.VipsImage, &tmp, C.double(sigma)) != 0 { | ||||
| 	if C.vips_apply_filters(img.VipsImage, &tmp, C.double(blurSigma), C.double(sharpSigma), C.int(pixelatePixels)) != 0 { | ||||
| 		return Error() | ||||
| 	} | ||||
|  | ||||
| 	C.swap_and_clear(&img.VipsImage, tmp) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (img *Image) Sharpen(sigma float32) error { | ||||
| 	var tmp *C.VipsImage | ||||
|  | ||||
| 	if C.vips_sharpen_go(img.VipsImage, &tmp, C.double(sigma)) != 0 { | ||||
| 		return Error() | ||||
| 	} | ||||
|  | ||||
| 	C.swap_and_clear(&img.VipsImage, tmp) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -34,8 +34,6 @@ int vips_image_get_array_int_go(VipsImage *image, const char *name, int **out, i | ||||
| void vips_image_set_array_int_go(VipsImage *image, const char *name, const int *array, int n); | ||||
|  | ||||
| int vips_addalpha_go(VipsImage *in, VipsImage **out); | ||||
| int vips_premultiply_go(VipsImage *in, VipsImage **out); | ||||
| int vips_unpremultiply_go(VipsImage *in, VipsImage **out); | ||||
|  | ||||
| int vips_copy_go(VipsImage *in, VipsImage **out); | ||||
|  | ||||
| @@ -44,8 +42,6 @@ int vips_rad2float_go(VipsImage *in, VipsImage **out); | ||||
|  | ||||
| int vips_resize_go(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); | ||||
| @@ -64,8 +60,7 @@ int vips_trim(VipsImage *in, VipsImage **out, double threshold, | ||||
|               gboolean smart, double r, double g, double b, | ||||
|               gboolean equal_hor, gboolean equal_ver); | ||||
|  | ||||
| int vips_gaussblur_go(VipsImage *in, VipsImage **out, double sigma); | ||||
| int vips_sharpen_go(VipsImage *in, VipsImage **out, double sigma); | ||||
| int vips_apply_filters(VipsImage *in, VipsImage **out, double blur_sigma, double sharp_sigma, int pixelate_pixels); | ||||
|  | ||||
| int vips_flatten_go(VipsImage *in, VipsImage **out, double r, double g, double b); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user