Please bring back plug-in-unsharp-mask

It looks like plug-in-unsharp-mask by Winston Chang has been removed in favour of a script-fu-unsharp-mask.
But the script-fu does not work as the plug-in.
I cannot see how its result sharpens an image.
My result for example is this:

I want that egg-shape sharpened, which worked fine from a script with the plug-in.
Now I get something I do not know what to do with.
The transparent background is gone … it’s not sharpened.
I’m clueless with such a result.

So what’s the proper way to sharpen things from a python script?
Just bring that Winston Chang plug-in back, please.

@nelo Hi! It looks like the compatibility function was removed as part of a final clean-up of unused functions (internally in GIMP at least): Issue #11653: Revise plug-in procedures that convert parameters from… (6ac92054) · Commits · GNOME / GIMP · GitLab

From the commit, we’ll try to add a general API that lets you apply any GEGL filter shortly after 3.0. However, it looks like there’s a way to access GEGL filters directly in Python in the meantime: GEGL operations exposed to Python-Fu - WIP 72 ops wrapped • GIMP Chat

You could have left the working one ( until there is a better solution)
and remove the one that produces a useless result.
I still can’t see how this script-fu thing sharpens an image.
It removes my transparent background and produces layers … for what?

Does Filters > Enhance > Sharpen (Unsharp Mask) (mentioned in the comments in that commit, as an alternative to the removed plugin) not work for you? On my F41 system running GIMP 2.99.19, it appears to offer an interactive parameter interface with live preview, and doesn’t remove my image’s alpha layer when applied.

(Edit: Oh, sorry, never mind. You wanted something scriptable. My mistake.)

I didn’t make the decision, but the reason was that if we left those functions in for 3.0, then we’d have to support it until GIMP 4 comes out. So there would be conflicts with the old limited way and the new flexible method.

Running the Script-Fu version on an image, I see that the extra layers serve to sharpen the image - if I toggle them off, the image becomes blurrier again. It’s not as nice as the GEGL operation though.

Finally found the solution by copying from goat-exercise.

This is the gegl code I needed:

gegl:unsharp-mask
    std-dev=3
    scale=0.5
    threshold=0

Now at the place in my code where the old unsharp-mask plugin was removed I put this:

intersect, x, y, width, height = easteregg_lay.mask_intersect()
    if intersect:
        Gegl.init(None)

        buffer = easteregg_lay.get_buffer()
        shadow_buffer = easteregg_lay.get_shadow_buffer()

        graph = Gegl.Node()
        in_put = graph.create_child("gegl:buffer-source")
        in_put.set_property("buffer", buffer)
        unsharp = graph.create_child("gegl:unsharp-mask")
        unsharp.set_property("std-dev", 3)
        unsharp.set_property("scale", 0.5)
        unsharp.set_property("threshold", 0)
        output = graph.create_child("gegl:write-buffer")
        output.set_property("buffer", shadow_buffer)
        in_put.link(unsharp)
        unsharp.link(output)
        output.process()

        # This is extremely important in bindings, since we don't
        # unref buffers. If we don't explicitly flush a buffer, we
        # may left hanging forever. This step is usually done
        # during an unref().
        shadow_buffer.flush()

        easteregg_lay.merge_shadow(True)
        easteregg_lay.update(x, y, width, height)

easteregg_lay is my layer in question.

Maybe this helps others struggling with similar problems.

PS.: “input” was replaced by “in_put” because
PyCharm said "shadows built-in name ‘input’ ".
So I thought it’s better to use something else.

One more example with gegl:lens-distortion:

intersect, x, y, width, height = text_layer.mask_intersect()
            if intersect:
                Gegl.init(None)

                buffer = text_layer.get_buffer()
                shadow_buffer = text_layer.get_shadow_buffer()

                graph = Gegl.Node()
                in_put = graph.create_child("gegl:buffer-source")
                in_put.set_property("buffer", buffer)
                lens = graph.create_child("gegl:lens-distortion")
                lens.set_property("x-shift", 0)
                lens.set_property("y-shift", 0)
                lens.set_property("main", 100)
                lens.set_property("edge", 0)
                lens.set_property("zoom", 10 * factor)
                lens.set_property("brighten", 0)
                output = graph.create_child("gegl:write-buffer")
                output.set_property("buffer", shadow_buffer)
                in_put.link(lens)
                lens.link(output)
                output.process()

                shadow_buffer.flush()

                text_layer.merge_shadow(True)  # Push merge to undo stack?
                text_layer.update(x, y, width, height)

where “text_layer” is the layer in question

Where does one find the list of available Gegl ops (lens-distortion here) and the description of the parameters? And can this be retrieved dynamically?

Edit: Answer: Gegl.list_operations(), now, for the parameters…

Edit2: Answer2: Gegl.Operation.list_properties(‘gegl:lens-distortion’)

So there is a way to write something quite generic to call a GEGL op in a single line of Python. I think I know what I’ll spend tomorrow on.

Full list is here: GEGL operations

Thx.

But these are the standard ones, this doesn’t include any plugins (but it’s nice to know what the standard ones do).

Yes, that’s where I have found the names and parameters

I am pursuing the same goal I think. I am managing to replace some of the pdb plugins that have disappeared with functions that contain Gegl code. For example hsv-noise

def HSV_Noise(self, drawable, dullset, hueset, satset, valset):

    drawwidth = drawable.get_width()
    drawheight = drawable.get_height()

    draw_buffer = drawable.get_buffer()
    draw_shad_buffer = drawable.get_shadow_buffer()

    graph = Gegl.Node()

    draw_in = graph.create_child("gegl:buffer-source")
    draw_in.set_property("buffer", draw_buffer)

    hsvnoise = graph.create_child("gegl:noise-hsv")
    hsvnoise.set_property("holdness", dullset)
    hsvnoise.set_property("hue-distance", hueset)
    hsvnoise.set_property("saturation-distance", satset)
    hsvnoise.set_property("value-distance", valset)
    hsvnoise.set_property("seed", random.randint(1, 16384))

    output = graph.create_child("gegl:write-buffer")
    output.set_property("buffer", draw_shad_buffer)

    draw_in.connect("output", hsvnoise, "input")
    hsvnoise.connect("output", output, "input")

    output.process()

    draw_shad_buffer.flush()
    drawable.merge_shadow(True)
    drawable.update(0, 0, drawwidth, drawheight)
    Gimp.displays_flush()

    return

This can then be called from my plugin with
self.HSV_Noise(drawable, dullset, hueset, satset, valset)

where the parameters are the working layer are the values for Dulling, Hue, Saturation and Value.

But I have problems with some of the Gegl operations.

This topic was automatically closed 45 days after the last reply. New replies are no longer allowed.