|
GimpChat Member |
|
Joined: Oct 31, 2020 Posts: 1450
|
https://gegl.org/operations/gegl-weighted-blend.htmlThis 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 [ 418.49 KiB | Viewed 1414 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 codeIn 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'."))
|
|