It is currently Sat Aug 15, 2026 10:06 am


All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: I am making GEGL filters and need help
PostPosted: Sun May 08, 2022 1:32 pm  (#1) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 2013
Here are two GEGL sharpen filters I made. They work fine.

https://github.com/LinuxBeaver/GEGL_hig ... _curvature
https://github.com/LinuxBeaver/High-Pas ... -Box-Blur-

but I have another filter I made "stroke ouline" and I want to give it multiple outlines but don't know how

Image

The c file is here so maybe someone can tinker with it and make multiple outlines like this.
/* 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 2006, 2010 Øyvind Kolås <[email protected]>
*/

#include "config.h"
#include <glib/gi18n-lib.h>


#ifdef GEGL_PROPERTIES

/* Should correspond to GeglMedianBlurNeighborhood in median-blur.c */
enum_start (gegl_stroke_grow_shape)
  enum_value (GEGL_stroke_GROW_SHAPE_SQUARE,  "square",  N_("Square"))
  enum_value (GEGL_stroke_GROW_SHAPE_CIRCLE,  "circle",  N_("Circle"))
  enum_value (GEGL_stroke_GROW_SHAPE_DIAMOND, "diamond", N_("Diamond"))
enum_end (GeglstrokeGrowShape)



property_double (radius, _("Blur radius"), 10.0)
  value_range   (0.0, 2)
  ui_range      (0.0, 300.0)
  ui_steps      (1, 5)
  ui_gamma      (1.5)
  ui_meta       ("unit", "pixel-distance")

property_enum   (grow_shape, _("Grow shape"),
                 GeglstrokeGrowShape, gegl_stroke_grow_shape,
                 GEGL_stroke_GROW_SHAPE_CIRCLE)
  description   (_("The shape to expand or contract the stroke in"))

property_double (grow_radius, _("Grow radius"), 12.0)
  value_range   (-100.0, 100.0)
  ui_range      (-50.0, 50.0)
  ui_digits     (0)
  ui_steps      (1, 5)
  ui_gamma      (1.5)
  ui_meta       ("unit", "pixel-distance")
  description (_("The distance to expand the stroke before blurring; a negative value will contract the stroke instead"))

property_color  (color, _("Color"), "white")
    /* TRANSLATORS: the string 'black' should not be translated */
  description   (_("The stroke's color (defaults to 'white')"))

/* It does make sense to sometimes have opacities > 1 (see GEGL logo
* for example)
*/
property_double (opacity, _("Opacity"), 1)
  value_range   (0.0, 2.0)
  ui_steps      (0.01, 0.10)

#else

#define GEGL_OP_META
#define GEGL_OP_NAME     stroke
#define GEGL_OP_C_SOURCE stroke.c

#include "gegl-op.h"

typedef struct
{
  GeglNode *input;
  GeglNode *grow;
  GeglNode *darken;
} State;

static void
update_graph (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  State *state = o->user_data;
  if (!state) return;

  if (o->grow_radius > 0.0001)
  {
    gegl_node_link_many (state->input, state->grow, state->darken, NULL);
  }
  else
  {
    gegl_node_link_many (state->input, state->darken, NULL);
  }
}


/* in attach we hook into graph adding the needed nodes */
static void
attach (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  GeglNode  *gegl = operation->node;
  GeglNode  *input, *output, *over, *translate, *opacity, *grow, *blur, *darken, *color;
  GeglColor *black_color = gegl_color_new ("rgb(0.0,0.0,0.0)");

  input     = gegl_node_get_input_proxy (gegl, "input");
  output    = gegl_node_get_output_proxy (gegl, "output");
  over      = gegl_node_new_child (gegl, "operation", "gegl:over", NULL);
  translate = gegl_node_new_child (gegl, "operation", "gegl:translate", NULL);
  opacity   = gegl_node_new_child (gegl, "operation", "gegl:opacity", NULL);
  blur      = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur",
                                         "clip-extent", FALSE,
                                         "abyss-policy", 0,
                                         NULL);
  grow      = gegl_node_new_child (gegl, "operation", "gegl:median-blur",
                                         "percentile",       100.0,
                                         "alpha-percentile", 100.0,
                                         "abyss-policy",     GEGL_ABYSS_NONE,
                                         NULL);
  darken    = gegl_node_new_child (gegl, "operation", "gegl:src-in", NULL);
  color     = gegl_node_new_child (gegl, "operation", "gegl:color",
                                   "value", black_color,
                                   NULL);
  State *state = g_malloc0 (sizeof (State));
  o->user_data = state;
  state->input = input;
  state->grow = grow;
  state->darken = darken;

  g_object_unref (black_color);

  gegl_node_link_many (input, grow, darken, blur, opacity, translate, over, output,
                       NULL);
  gegl_node_connect_from (over, "aux", input, "output");
  gegl_node_connect_from (darken, "aux", color, "output");

  gegl_operation_meta_redirect (operation, "grow-shape", grow, "neighborhood");
  gegl_operation_meta_redirect (operation, "grow-radius", grow, "radius");
  gegl_operation_meta_redirect (operation, "radius", blur, "std-dev-x");
  gegl_operation_meta_redirect (operation, "radius", blur, "std-dev-y");
  gegl_operation_meta_redirect (operation, "color", color, "value");
  gegl_operation_meta_redirect (operation, "opacity", opacity, "value");
}

static void
dispose (GObject *object)
{
   GeglProperties  *o = GEGL_PROPERTIES (object);
   g_clear_pointer (&o->user_data, g_free);
   G_OBJECT_CLASS (gegl_op_parent_class)->dispose (object);
}

static void
gegl_op_class_init (GeglOpClass *klass)
{
  GObjectClass           *object_class;
  GeglOperationClass     *operation_class      = GEGL_OPERATION_CLASS (klass);
  GeglOperationMetaClass *operation_meta_class = GEGL_OPERATION_META_CLASS (klass);

  operation_class->attach      = attach;
  operation_meta_class->update = update_graph;

  object_class               = G_OBJECT_CLASS (klass);
  object_class->dispose      = dispose;

  gegl_operation_class_set_keys (operation_class,
    "name",        "gegl:stroke",
    "title",       _("stroke"),
    "categories",  "light",
    "reference-hash", "1784365a0e801041189309f3a4866b1a",
    "description",
    _("Creates a stroke outline around images in transparency"),
    NULL);
}

#endif


Image


Lastly, I don't want to sound prejudice but I wish everyone made GEGL filters instead of using the legacy system.


Share on Facebook Share on Twitter Share on Orkut Share on Digg Share on MySpace Share on Delicious Share on Technorati
Top
 Post subject: Re: I am making GEGL filters and need help
PostPosted: Sun May 08, 2022 1:34 pm  (#2) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 2013
Here is the github page of the stroke filter.
https://github.com/LinuxBeaver/GEGL_Stroke


Top
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


cron

* Login  



Powered by phpBB3 © phpBB Group