mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-06-17 22:37:33 +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
|
||||
}
|
||||
|
||||
|
162
vips/vips.c
162
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) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
vips_sharpen_go(VipsImage *in, VipsImage **out, double sigma) {
|
||||
return vips_sharpen(in, out, "sigma", sigma, NULL);
|
||||
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