Calling Filters from Plug-Ins
[Theory] Introduction
If you also read the How to write a filter tutorial, you know that filters in GIMP are GEGL operations.
There are a few ways to work with these in a plug-in. One of these ways
is to request a GeglBuffer
with
gimp_drawable_get_buffer()
and directly use GEGL API on this buffer. This is very
powerful as you have the full API access. You can not only run filters,
but also iterate directly through the buffer, in any color format you
wish to.
Now it also has limitations regarding the specific usage in GIMP:
- It requires working on the plug-in side;
- It may not be as efficient;
- You don’t have access to some specific filters which are only
available in our codebase, such as
"gimp:curves"
,"gimp:color-balance"
,"gimp:levels"
, all layer mode operations, and many more; - You cannot create non-destructive filters.
Therefore this tutorial will not talk much further about this
possibility. You may look up a GEGL tutorial if you want to do this.
Instead we will show specific libgimp
API to run filters, especially
for the non-destructive use cases.
[Code] Applying a Filter Non-Destructively in C
Let’s say I want to run "zemarmot:hello-world-meta"
filter we created in the filter tutorial.
In C, this is basically a one-liner with the variable-length arguments
function gimp_drawable_append_new_filter()
:
gimp_drawable_append_new_filter (drawable, "zemarmot:hello-world-meta",
"Hello World", GIMP_LAYER_MODE_REPLACE, 1.0,
"text", "Hello World!",
"compute-size", FALSE,
"font-size", 100.0,
NULL);
As expected, when not setting an argument, the default value is implied.
The return value is the appended GimpDrawableFilter
,
which can be further edited if needed.
You may also be interested into the counterpart function
gimp_drawable_merge_new_filter()
which immediately merge the render onto the drawable, hence works
destructively. As a consequence, no GimpDrawableFilter
object is
returned.
[Code] Applying a Filter Non-Destructively in Python
Now you probably already guessed that this won’t work in Python because of the lack of introspection for varargs functions. This is the slightly longer variant for Python:
filter = Gimp.DrawableFilter.new(drawable, "zemarmot:hello-world-meta", "Hello World")
filter.set_blend_mode(Gimp.LayerMode.REPLACE)
filter.set_opacity(1.0)
config = filter.get_config()
config.set_property('text', 'Hello World!')
config.set_property('compute-size', False)
config.set_property('font-size', 100.0)
filter.update()
drawable.append_filter(filter)
You may recognize a very similar logic as how we would run PDB
procedures.
The config
object is again from a subclass of
GimpDrawableFilterConfig
generated on-the-fly with all the arguments of the called filter.
Note that any argument update to this config
object is not immediately
transmitted to the core process. Instead all the changes are sent at
once when calling
gimp_drawable_filter_update()
.
This doesn’t really change anything here, but it would if the filter had already been applied and you want to update its arguments without re-rendering at every argument change.
[Code] Applying a Filter Non-Destructively in Script-Fu
Script-Fu has its own special binding around the
gimp_drawable_append_new_filter()
function:
(gimp-drawable-append-new-filter 2 "zemarmot:hello-world-meta" "hello world" LAYER-MODE-REPLACE 1.0
#:text "Hello World!"
#:compute-size 0
#:font-size 100.0)
You may recognize the special named argument syntax (#:arg
), as for calling
plug-in PDB procedures
which mainly implies that you do not have to set all arguments and can
set them in any order.
And just as the C function, this returns a GimpDrawableFilter
which
you may further work on.
This makes it quite similar to the libgimp
C function!
Very similarly a (gimp-drawable-merge-new-filter)
binding exists,
which does not return any GimpDrawableFilter
.
Conclusion
The simplicity on running any type of filter in the 3.0 API is one of
the huge improvements over libgimp
v2 API, as we used to only be able
to work directly with GEGL
API on plug-in side.
Furthermore it used to be only available to compiled plug-ins. Now it
works for any GObject-Introspected
binding and even in Script-Fu.
To go further, the libgimp API reference will help you figure out all advanced usage.
(H)API hacking!
- Back to “How to write a plug-in” tutorial index
- Previous tutorial: Script-Fu plug-ins