[gegl] focus-blur: new op in common-cxx
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] focus-blur: new op in common-cxx
- Date: Thu, 14 May 2020 21:50:55 +0000 (UTC)
commit 1de5e5cd825b20418fd5fe0c2ec203a43a6fc7ff
Author: Ell <ell_se yahoo com>
Date: Thu May 14 22:00:44 2020 +0300
focus-blur: new op in common-cxx
Add a new gegl:focus-blur, which blurs the image around a focal
point, allowing the geometry of the focus region to be adjusted.
It can be used to create fake depth-of-field effects.
This op is simply a front-end for gegl:variable-blur with
gegl:vignette as the mask. It's a C op that lives in common-cxx
for the same reason as gegl:variable-blur (see last commit).
operations/common-cxx/focus-blur.c | 269 +++++++++++++++++++++++++++++++++++++
operations/common-cxx/meson.build | 1 +
po/POTFILES.in | 1 +
3 files changed, 271 insertions(+)
---
diff --git a/operations/common-cxx/focus-blur.c b/operations/common-cxx/focus-blur.c
new file mode 100644
index 000000000..51dc87ca1
--- /dev/null
+++ b/operations/common-cxx/focus-blur.c
@@ -0,0 +1,269 @@
+/* This file is an image processing operation for GEGL
+ *
+ * GEGL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
+ *
+ * Copyright 2020 Ell
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+#include <math.h>
+
+#define MAX_GAMMA 1000.0
+
+#ifdef GEGL_PROPERTIES
+
+enum_start (gegl_focus_blur_shape)
+ enum_value (GEGL_FOCUS_BLUR_SHAPE_CIRCLE, "circle", N_("Circle"))
+ enum_value (GEGL_FOCUS_BLUR_SHAPE_SQUARE, "square", N_("Square"))
+ enum_value (GEGL_FOCUS_BLUR_SHAPE_DIAMOND, "diamond", N_("Diamond"))
+ enum_value (GEGL_FOCUS_BLUR_SHAPE_HORIZONTAL, "horizontal", N_("Horizontal"))
+ enum_value (GEGL_FOCUS_BLUR_SHAPE_VERTICAL, "vertical", N_("Vertical"))
+enum_end (GeglFocusBlurShape)
+
+property_double (blur_radius, _("Blur radius"), 25.0)
+ description (_("Out-of-focus blur radius"))
+ value_range (0.0, 1500.0)
+ ui_range (0.0, 100.0)
+ ui_gamma (2.0)
+ ui_meta ("unit", "pixel-distance")
+
+property_int (blur_levels, _("Blur levels"), 8)
+ description (_("Number of blur levels"))
+ value_range (2, 16)
+
+property_enum (shape, _("Shape"),
+ GeglFocusBlurShape,
+ gegl_focus_blur_shape,
+ GEGL_FOCUS_BLUR_SHAPE_CIRCLE)
+
+property_double (x, _("Center X"), 0.5)
+ ui_range (0, 1.0)
+ ui_meta ("unit", "relative-coordinate")
+ ui_meta ("axis", "x")
+
+property_double (y, _("Center Y"), 0.5)
+ ui_range (0, 1.0)
+ ui_meta ("unit", "relative-coordinate")
+ ui_meta ("axis", "y")
+
+property_double (radius, _("Radius"), 0.75)
+ description (_("Focus-region outer radius"))
+ value_range (0.0, G_MAXDOUBLE)
+ ui_range (0.0, 5.0)
+ ui_meta ("unit", "relative-distance")
+
+property_double (focus, _("Sharpness"), 0.25)
+ description (_("Focus-region inner limit"))
+ value_range (0.0, 1.0)
+
+property_double (midpoint, _("Midpoint"), 0.5)
+ description (_("Focus-transition midpoint"))
+ value_range (0.0, 1.0)
+
+property_double (aspect_ratio, _("Aspect ratio"), 0.0)
+ value_range (-1.0, +1.0)
+
+property_double (rotation, _("Rotation"), 0.0)
+ value_range (-180.0, +180.0)
+ ui_meta ("unit", "degree")
+ ui_meta ("direction", "cw")
+
+#else
+
+#define GEGL_OP_META
+#define GEGL_OP_NAME focus_blur
+#define GEGL_OP_C_SOURCE focus-blur.c
+
+#include "gegl-op.h"
+
+typedef struct
+{
+ GeglNode *input;
+ GeglNode *output;
+
+ GeglNode *color;
+ GeglNode *crop;
+ GeglNode *vignette;
+
+ GeglNode *variable_blur;
+} Nodes;
+
+static void
+update (GeglOperation *operation)
+{
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+ Nodes *nodes = o->user_data;
+
+ if (nodes)
+ {
+ GeglColor *color;
+ gdouble scale;
+ gdouble squeeze;
+
+ color = gegl_color_new ("black");
+
+ gegl_node_set (nodes->color,
+ "value", color,
+ NULL);
+
+ g_object_unref (color);
+
+ color = gegl_color_new ("white");
+
+ if (o->aspect_ratio >= 0.0)
+ scale = 1.0 - o->aspect_ratio;
+ else
+ scale = 1.0 / (1.0 + o->aspect_ratio);
+
+ if (scale <= 1.0)
+ squeeze = +2.0 * atan (1.0 / scale - 1.0) / G_PI;
+ else
+ squeeze = -2.0 * atan (scale - 1.0) / G_PI;
+
+ gegl_node_set (nodes->vignette,
+ "color", color,
+ "shape", o->shape,
+ "radius", o->radius,
+ "softness", 1.0 - o->focus,
+ "gamma", o->midpoint < 1.0 ?
+ MIN (log (0.5) / log (o->midpoint),
+ MAX_GAMMA) :
+ MAX_GAMMA,
+ "squeeze", squeeze,
+ "x", o->x,
+ "y", o->y,
+ "rotation", fmod (o->rotation + 360.0, 360.0),
+ NULL);
+
+ g_object_unref (color);
+ }
+}
+
+static void
+attach (GeglOperation *operation)
+{
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+ Nodes *nodes;
+
+ if (! o->user_data)
+ o->user_data = g_slice_new (Nodes);
+
+ nodes = o->user_data;
+
+ nodes->input = gegl_node_get_input_proxy (operation->node, "input");
+ nodes->output = gegl_node_get_output_proxy (operation->node, "output");
+
+ nodes->color = gegl_node_new_child (
+ operation->node,
+ "operation", "gegl:color",
+ NULL);
+
+ nodes->crop = gegl_node_new_child (
+ operation->node,
+ "operation", "gegl:crop",
+ NULL);
+
+ nodes->vignette = gegl_node_new_child (
+ operation->node,
+ "operation", "gegl:vignette",
+ "proportion", 0.0,
+ NULL);
+
+ nodes->variable_blur = gegl_node_new_child (
+ operation->node,
+ "operation", "gegl:variable-blur",
+ "linear-mask", TRUE,
+ NULL);
+
+ gegl_node_link_many (nodes->input,
+ nodes->variable_blur,
+ nodes->output,
+ NULL);
+
+ gegl_node_link_many (nodes->color,
+ nodes->crop,
+ nodes->vignette,
+ NULL);
+
+ gegl_node_connect_to (nodes->input, "output",
+ nodes->crop, "aux");
+
+ gegl_node_connect_to (nodes->vignette, "output",
+ nodes->variable_blur, "aux");
+
+ gegl_operation_meta_redirect (operation, "blur-radius",
+ nodes->variable_blur, "radius");
+ gegl_operation_meta_redirect (operation, "blur-levels",
+ nodes->variable_blur, "levels");
+
+ gegl_operation_meta_watch_nodes (operation,
+ nodes->color,
+ nodes->crop,
+ nodes->vignette,
+ nodes->variable_blur,
+ NULL);
+
+ update (operation);
+}
+
+static void
+my_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ set_property (object, property_id, value, pspec);
+
+ update (GEGL_OPERATION (object));
+}
+
+static void
+dispose (GObject *object)
+{
+ GeglProperties *o = GEGL_PROPERTIES (object);
+
+ if (o->user_data)
+ {
+ g_slice_free (Nodes, o->user_data);
+
+ o->user_data = NULL;
+ }
+
+ G_OBJECT_CLASS (gegl_op_parent_class)->dispose (object);
+}
+
+static void
+gegl_op_class_init (GeglOpClass *klass)
+{
+ GObjectClass *object_class;
+ GeglOperationClass *operation_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ operation_class = GEGL_OPERATION_CLASS (klass);
+
+ object_class->dispose = dispose;
+ object_class->set_property = my_set_property;
+
+ operation_class->attach = attach;
+
+ gegl_operation_class_set_keys (operation_class,
+ "name", "gegl:focus-blur",
+ "title", _("Focus Blur"),
+ "categories", "blur",
+ "description", _("Blur the image around a focal point"),
+ NULL);
+}
+
+#endif
diff --git a/operations/common-cxx/meson.build b/operations/common-cxx/meson.build
index 02b63ee8b..fbbb0b120 100644
--- a/operations/common-cxx/meson.build
+++ b/operations/common-cxx/meson.build
@@ -1,6 +1,7 @@
gegl_common_cxx_sources = files(
'distance-transform.cc',
+ 'focus-blur.c',
'piecewise-blend.cc',
'variable-blur.c',
'warp.cc',
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 14653c249..8806cb50f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -126,6 +126,7 @@ operations/common/wavelet-blur.c
operations/common/weighted-blend.c
operations/common/write-buffer.c
operations/common-cxx/distance-transform.cc
+operations/common-cxx/focus-blur.c
operations/common-cxx/piecewise-blend.cc
operations/common-cxx/variable-blur.c
operations/common-cxx/warp.cc
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]