It is currently Thu Jun 27, 2024 12:56 pm


All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: GEGL Vibrance - fancy saturation plugin (probably canceled)
PostPosted: Tue Jan 30, 2024 10:02 am  (#1) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 1446
This plugin is near the end of its development which started a day or two ago, and the download source and binaries will be here soon.

About the plugin
Adobe Photoshop and GMIC have a filter named Vibrance that is basically Saturation on an alternative blend mode with a few other things. I decided to make my own Vibrance filter in GEGL to mimic them. I even added features; hyper opacity and blend mode switchers, which no other vibrance filter has to make sure I am original.

Vibrance being applied on the turtle. The blend mode is actually "LCH Lightness" and it was accidentally named screen in the drop down list of this beta build. So I had to fuzz it out.
Attachment:
lighten.png
lighten.png [ 607.3 KiB | Viewed 1424 times ]


Currently, my Vibrance filter allows the user to choose between four blend modes (lighten only, screen, overlay and addition) with a slider called hyper opacity which allows the blend mode to above 100% (up to 200%). And still giving the user the ability to adjust normal saturation and lightness after the 'vibrance' is applied. In the industry "Vibrance" is a term that describes saturation on an alternative blend mode. I am fully aware Gimp's default saturation filter can be blended to make a "vibrance" effect but it cannot do the hyper opacity, lightness and saturation/desaturation on it. Though it does have the advantage of using all Gimp's blend modes and not just a few of them. I may add more blend modes before it is released.

Video preview of Vibrance
https://streamable.com/1mwmgr


Last edited by contrast_ on Fri Mar 29, 2024 12:06 am, edited 1 time in total.

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: GEGL Vibrance - fancy saturation plugin (coming soon)
PostPosted: Tue Jan 30, 2024 11:53 am  (#2) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 1446
Vibrance now has 8 blend modes to choose from instead of just 4 (like it did a few hours ago). Plus, Screen, Lighten, Overlay, Weighted Blend, Addition, LCh Lightness and Soft Light. I have never made a GEGL plugin that used the "Weighted blend" blend mode. This is a GEGL exclusive blend mode that happens to look good with it.

here is a snip of the code that list the blend modes.
switch (o->blendmode) {
        break;
    case PLUS:
  gegl_node_link_many (state->input, state->plus, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->plus, "aux", state->opacity, "output");
        break;
    case SCREEN:
  gegl_node_link_many (state->input, state->screen, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->screen, "aux", state->opacity, "output");
        break;
    case LIGHTEN:
  gegl_node_link_many (state->input, state->lighten, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->lighten, "aux", state->opacity, "output");
        break;
    case OVERLAY:
  gegl_node_link_many (state->input, state->overlay, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->overlay, "aux", state->opacity, "output");
        break;
    case WB:
  gegl_node_link_many (state->input, state->wb, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->wb, "aux", state->opacity, "output");
        break;
    case ADD:
  gegl_node_link_many (state->input, state->add, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->add, "aux", state->opacity, "output");
        break;
    case LIGHTEN2:
  gegl_node_link_many (state->input, state->lighten2, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->lighten2, "aux", state->opacity, "output");
        break;
    case SOFTLIGHT:
  gegl_node_link_many (state->input, state->softlight, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->softlight, "aux", state->opacity, "output");
    }
  }


Top
 Post subject: Re: GEGL Vibrance - fancy saturation plugin (coming soon)
PostPosted: Tue Jan 30, 2024 12:20 pm  (#3) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 1446
https://gegl.org/operations/gegl-weighted-blend.html

This is a GEGL exclusive blend mode called Weighted Blend that is NOT natively inside Gimp. I have never used this blend mode before, but it looks amazing. So good that I might make it the default.

Attachment:
image.png
image.png [ 418.49 KiB | Viewed 1406 times ]


Look how it is listed inside the code

it was given the name wb in the new child operation list and WB in the ENUM drop down list area. So look for that.

/* 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 Øyvind Kolås <pippin@gimp.org>
* 2024 Beaver, GEGL Vibrance

Test this filter without installing by pasting this GEGL Syntax inside Gimp's GEGL Graph filter

id=1 add aux=[ ref=1 saturation scale=2 opacity value=1.0 ]
hue-chroma lightness=-29
end of syntax

THIS FILTER WAS INSPIRED BY GMIC AND A FILTER I SAW INSIDE IN ADOBE PHOTOSHOP CS5 (i'm sure GMIC was inspired by Photoshop CS too)

*/

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

#ifdef GEGL_PROPERTIES

enum_start (vibrance_magic)
  enum_value (PLUS,      "Plus",
              N_("Plus"))
  enum_value (SCREEN,      "screen",
              N_("Screen"))
  enum_value (LIGHTEN,      "lighten",
              N_("LCh Lightness"))
  enum_value (OVERLAY,      "overlay",
              N_("Overlay"))
  enum_value (WB,      "wb",
              N_("Weighted Blend"))
  enum_value (ADD,      "add",
              N_("Addition"))
  enum_value (LIGHTEN2,      "lighten2",
              N_("Lighten Only"))
  enum_value (SOFTLIGHT,      "softlight",
              N_("Soft Light"))
enum_end (vibrancemagic)


enum_start (gegl_saturation_typebv)
  enum_value (GEGL_SATURATION_TYPE_NATIVE,  "Native",  N_("Native"))
  enum_value (GEGL_SATURATION_TYPE_CIE_LAB, "CIE-Lab", N_("CIE Lab/Lch"))
  enum_value (GEGL_SATURATION_TYPE_CIE_YUV, "CIE-Yuv", N_("CIE Yuv"))
enum_end (GeglSaturationTypebv)


property_enum (colorspacevibrance, _("Interpolation Color Space of Vibrance"),
    description(_("Native is the default but feel free to try other saturation algorithms."))
    GeglSaturationTypebv, gegl_saturation_typebv,
    GEGL_SATURATION_TYPE_NATIVE)


property_enum (blendmode, _("Blend Mode of Vibrance"),
    vibrancemagic, vibrance_magic,
    ADD)
   description  (_("Blend mode of the saturation operation that we term 'vibrance'."))

property_double (vibrance, _("Vibrance (Blended Saturation)"), 1.0)
   description (_("Saturation on the addition blend mode makes a vibrance effect."))
   value_range (0.0, 6.0)
   ui_range    (0.0, 5.0)

property_double (hyperopacity, _("Hyper Opacity"), 1.0)
   description (_("Opacity slider of the blend mode. Blend mode opacity can go up to 200% and low as 5%. "))
   value_range (0.05, 2.0)
   ui_range    (0.2, 2.0)

property_double (saturation, _("Normal Saturation"), 1.0)
   description (_("Perform a normal Saturation after the vibrance"))
   value_range (0.0, 2.0)
   ui_range    (0.0, 2.0)

property_double (lightness, _("Lightness"), 0.0)
   description (_("Perform a lightness boost after the vibrance."))
   value_range (-20.0, 10.0)
   ui_range    (-20.0, 10.0)

#else

#define GEGL_OP_META
#define GEGL_OP_NAME     vibrance
#define GEGL_OP_C_SOURCE vibrance.c

#include "gegl-op.h"

typedef struct
{
GeglNode *input;
GeglNode *output;
GeglNode *lightness;
GeglNode *lighten;
GeglNode *lighten2;
GeglNode *softlight;
GeglNode *saturation;
GeglNode *saturation2;
GeglNode *plus;
GeglNode *add;
GeglNode *wb;
GeglNode *overlay;
GeglNode *screen;
GeglNode *opacity;
}State;

static void attach (GeglOperation *operation)
{
  GeglNode *gegl = operation->node;
  GeglProperties *o = GEGL_PROPERTIES (operation);

  State *state = o->user_data = g_malloc0 (sizeof (State));

  state->input    = gegl_node_get_input_proxy (gegl, "input");
  state->output   = gegl_node_get_output_proxy (gegl, "output");


  state->lightness = gegl_node_new_child (gegl,
                                  "operation", "gegl:hue-chroma",
                                  NULL);

  state->saturation = gegl_node_new_child (gegl,
                                  "operation", "gegl:saturation",
                                  NULL);

  state->saturation2 = gegl_node_new_child (gegl,
                                  "operation", "gegl:saturation",
                                  NULL);

  state->plus = gegl_node_new_child (gegl,
                                  "operation", "gegl:plus",
                                  NULL);

  state->softlight = gegl_node_new_child (gegl,
                                  "operation", "gegl:soft-light",
                                  NULL);

  state->wb = gegl_node_new_child (gegl,
                                  "operation", "gegl:weighted-blend",
                                  NULL);

  state->opacity = gegl_node_new_child (gegl,
                                  "operation", "gegl:opacity",
                                  NULL);

  state->screen = gegl_node_new_child (gegl,
                                  "operation", "gegl:screen", "srgb", TRUE,
                                  NULL);

/*These four filters are Gimp exclusive and use numbers. if Gimp ever gets new blend modes they will break until the number is changed by 1

So in the future if this plugin breaks try changing the number from 36 to (34, or 37) and (22 or 24) on overlay. The blend mode will be one number off.

SAID FILTERS ARE LCH LIGHTNESS, LIGHTEN ONLY, OVERLAY  AND ADDITION*/
  state->lighten = gegl_node_new_child (gegl,
                                  "operation", "gimp:layer-mode", "layer-mode", 27,  "blend-space", 2,
                                  NULL);

  state->lighten2 = gegl_node_new_child (gegl,
                                  "operation", "gimp:layer-mode", "layer-mode", 36,  "blend-space", 0,
                                  NULL);

  state->overlay = gegl_node_new_child (gegl,
                                  "operation", "gimp:layer-mode", "layer-mode", 23, "blend-space", 2,
                                  NULL);

  state->add = gegl_node_new_child (gegl,
                                  "operation", "gimp:layer-mode", "layer-mode", 33, "blend-space", 0,
                                  NULL);

gegl_operation_meta_redirect (operation, "vibrance", state->saturation, "scale");
gegl_operation_meta_redirect (operation, "vibrance", state->saturation, "colorspace");
gegl_operation_meta_redirect (operation, "saturation", state->saturation2, "scale");
gegl_operation_meta_redirect (operation, "lightness", state->lightness, "lightness");
gegl_operation_meta_redirect (operation, "hyperopacity", state->opacity, "value");

}

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

switch (o->blendmode) {
        break;
    case PLUS:
  gegl_node_link_many (state->input, state->plus, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->plus, "aux", state->opacity, "output");
        break;
    case SCREEN:
  gegl_node_link_many (state->input, state->screen, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->screen, "aux", state->opacity, "output");
        break;
    case LIGHTEN:
  gegl_node_link_many (state->input, state->lighten, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->lighten, "aux", state->opacity, "output");
        break;
    case OVERLAY:
  gegl_node_link_many (state->input, state->overlay, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->overlay, "aux", state->opacity, "output");
        break;
    case WB:
  gegl_node_link_many (state->input, state->wb, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->wb, "aux", state->opacity, "output");
        break;
    case ADD:
  gegl_node_link_many (state->input, state->add, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->add, "aux", state->opacity, "output");
        break;
    case LIGHTEN2:
  gegl_node_link_many (state->input, state->lighten2, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->lighten2, "aux", state->opacity, "output");
        break;
    case SOFTLIGHT:
  gegl_node_link_many (state->input, state->softlight, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->softlight, "aux", state->opacity, "output");
    }
  }

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

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

  gegl_operation_class_set_keys (operation_class,
    "name",        "lb:vibrance",
    "title",       _("Vibrance"),
    "reference-hash", "windows95virtualmachineplaysession000000",
    "description", _("This filter runs Saturation on different blend modes with a slider to make the blend mode go above 100%. The filter also has a lighting and normal saturation slider that comes after the blended saturation."),
    "gimp:menu-path", "<Image>/Colors",
    "gimp:menu-label", _("Vibrance"),
    NULL);
}

#endif



Below I will list all the areas that Weighted Blend is in so users can understand how the GEGL node gegl:weighted-blend integrates in the code

In the Typedef Structure that list all given nodes names (look for *wb)
#include "gegl-op.h"

typedef struct
{
GeglNode *input;
GeglNode *output;
GeglNode *lightness;
GeglNode *lighten;
GeglNode *lighten2;
GeglNode *softlight;
GeglNode *saturation;
GeglNode *saturation2;
GeglNode *plus;
GeglNode *add;
GeglNode *wb;
GeglNode *overlay;
GeglNode *screen;
GeglNode *opacity;
}State;


In the GEGL New Child Operation list
  state->wb = gegl_node_new_child (gegl,
                                  "operation", "gegl:weighted-blend",
                                  NULL);


In the ENUM (drop down list) internal area.
    case WB:
  gegl_node_link_many (state->input, state->wb, state->lightness, state->saturation2, state->output, NULL);
  gegl_node_link_many (state->input, state->saturation, state->opacity,  NULL);
  gegl_node_connect_from (state->wb, "aux", state->opacity, "output");
        break;


In the GUI aspect of ENUM list

enum_start (vibrance_magic)
  enum_value (PLUS,      "Plus",
              N_("Plus"))
  enum_value (SCREEN,      "screen",
              N_("Screen"))
  enum_value (LIGHTEN,      "lighten",
              N_("LCh Lightness"))
  enum_value (OVERLAY,      "overlay",
              N_("Overlay"))
  enum_value (WB,      "wb",
              N_("Weighted Blend"))
  enum_value (ADD,      "add",
              N_("Addition"))
  enum_value (LIGHTEN2,      "lighten2",
              N_("Lighten Only"))
  enum_value (SOFTLIGHT,      "softlight",
              N_("Soft Light"))
enum_end (vibrancemagic)

property_enum (blendmode, _("Blend Mode of Vibrance"),
    vibrancemagic, vibrance_magic,
    ADD)
   description  (_("Blend mode of the saturation operation that we term 'vibrance'."))


Top
 Post subject: Re: GEGL Vibrance - fancy saturation plugin (coming soon)
PostPosted: Tue Jan 30, 2024 3:00 pm  (#4) 
Offline
GimpChat Member

Joined: Oct 16, 2017
Posts: 41
Quote:
In the industry "Vibrance" is a term that describes saturation on an alternative blend mode.


No, it's not. Vibrance is weighted saturation, and weighing by saturation or chroma helps it avoid being over-saturated. I did `Vibrance [YCH]` for G'MIC which uses YCH model which is the cylindrical interpretation of YUV.


Top
 Post subject: Re: GEGL Vibrance - fancy saturation plugin (coming soon)
PostPosted: Tue Jan 30, 2024 4:08 pm  (#5) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 1446
ok I guess I was wrong.

I figured it had to be that because GMIC and PS's vibrance looks very similar Saturation by Gimp blend modes.


Top
 Post subject: Re: GEGL Vibrance - fancy saturation plugin (coming soon)
PostPosted: Tue Jan 30, 2024 5:25 pm  (#6) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 1446
I just wrote a bunch of GEGL syntax that dulls the color red from saturation but preserves everything else. It is sloppy because it depends on the original image file and not id and ref.

Attachment:
remove_red_and_preserve_blue_and_green.png
remove_red_and_preserve_blue_and_green.png [ 567.98 KiB | Viewed 1381 times ]


Top
 Post subject: Re: GEGL Vibrance - fancy saturation plugin (coming soon)
PostPosted: Fri Feb 02, 2024 4:02 pm  (#7) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 1446
I found a simple way to keep green and blue saturation but decrease red saturation using only a few lines of GEGL syntax.

The saturation is kept on green in the image but the red is reduced.
Attachment:
reduce_red.png
reduce_red.png [ 161.39 KiB | Viewed 1313 times ]


If I disable this line the red comes back
Attachment:
reduce_red_disabled.png
reduce_red_disabled.png [ 162.64 KiB | Viewed 1313 times ]


Top
 Post subject: Re: GEGL Vibrance - fancy saturation plugin (coming soon)
PostPosted: Fri Feb 02, 2024 7:27 pm  (#8) 
Offline
GimpChat Member
User avatar

Joined: Nov 04, 2015
Posts: 1362
I came across another way of boosting vibrance using the G'MIC channel overblur filter by Reptorian.


Image



Image


This filter can multiply each RGB channel. Its mostly too intense and I use colour curves to lighten it a bit.


Top
 Post subject: Re: GEGL Vibrance - fancy saturation plugin (coming soon)
PostPosted: Sun Feb 11, 2024 9:29 pm  (#9) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 1446
Image

I made a graph (aka GEGL syntax) that depends on my plugin Edge Smooth (which can be downloaded here as a dependency of chrome text)
https://github.com/LinuxBeaver/GEGL---C ... r/releases

This GEGL syntax saturates green and blue and ignores red almost entirely. I don't know why I should make it a filter when it can be entirely controlled in GEGL graph using the master opacity slider that all GEGL filters have. At 0% to 100% opacity the effect is controlled.

Paste this syntax into GEGL graph to "vibrance" an image and make sure to tweak the opacity slider of GEGL graph.
id=0
saturation scale=10
median-blur radius=0
id=1 gimp:layer-mode layer-mode=replace composite-mode=clip-to-layer opacity=0.30 aux=[ ref=1 color-to-alpha transparency-threshold=0.9 color=red   ]
id=2
gimp:layer-mode layer-mode=anti-erase aux=[ ref=2   gaussian-blur std-dev-x=50 std-dev-y=50 opacity value=1 ]
opacity value=1
lb:edgesmooth
dst-over aux=[ ref=0 opacity value=1 ]


Now why should I turn this into a plugin when the syntax and opacity slider does everything?


Top
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


   Similar Topics   Replies 
No new posts Attachment(s) GEGL Text Style Collection - plugin with many fancy text styles

14

No new posts Attachment(s) Baby's first GEGL plugin - a very basic GEGL plugin anyone can make.

9

No new posts Attachment(s) GEGL Background on top (first public GEGL plugin of 2024)

0

No new posts Attachment(s) GEGL Plastic Wrap plugin

1

No new posts Someone other then me made a GEGL plugin using my tactics

1



* Login  



Powered by phpBB3 © phpBB Group