Porting a GIMP2 python script to GIMP3 (original) (raw)
Hello all,
I am using Gimp2 since years and therefore I have implemented some for me useful python scripts. If I try to use them with Gimp3 (putting them to the plugin folder) they are not recognized at startup and I can not use them.
I attached one of my plugins at the end, maybe someone of the community could help me porting that in the way that I could use it with Gimp3.
I would be glad about some hints and help.
Kind regards Christoph
PS: If I am here with my question at the wrong place, please let me know.
#!/usr/bin/env python
from gimpfu import *
# script ##########################################################
def scaleH540(image, drawable) :
gprint("Function: scaleH540")
height = 540
numLayer, layer_ids = pdb.gimp_image_get_layers(image)
gprint("Number of layers: "+str(numLayer))
for i in range(0, numLayer):
layer=image.layers[i]
layerName=str(layer)
if layerName.upper().find('JPG') != -1:
aspect_ratio=float(layer.width)/float(layer.height)
newWidth = int(round(height*aspect_ratio))
gprint(str(i)+ ": "+layerName.upper().replace("<GIMP.LAYER '", "").replace("'>", "")+" - NewWidth: "+str(newWidth))
pdb.gimp_layer_scale(layer,newWidth,height,FALSE)
return
# script ##########################################################
# This is the plugin registration function
register(
"ScaleLayer",
"Scale 540 Height",
"This script does scale marked layers of the image",
"Christoph Raber",
"Christoph Raber",
"May 2021",
#"<Image>/MyScripts/My First Python-Fu",
#"<Image>/MyHelpers/Scale 6000",
"<Image>/MyHelpers/Scale Layers H540",
"*",
[
],
[],
scaleH540,
)
main()
nelo March 30, 2025, 9:24am 2
Instead of your script: could Kamil Burda’s “batcher” help?
alex666 March 30, 2025, 5:12pm 3
Great in principle!
But
- rejects any destination other than ~ for processed files
- unusable for my basic use:
reducing images while preserving their aspect ratio, so as to fit into a rectangle of x * y pixels, which can be done with BIMP.
This batcher does not help really because I would like to write my own scripts and so I am searching for help to port/use my old ones or at least for examples how to write and integrate scripts for and into the new Gimp3.
nelo March 30, 2025, 5:47pm 5
Official tutorial is here
https://testing.developer.gimp.org/resource/writing-a-plug-in/tutorial-python/
A good example also is the foggify.py plug-in which comes with GIMP
And api-docs are here:
Trouble with those docs: they are for C and not specifically for python.
But one can imagine most of the time what the python-terms are.
Using the search field can be a help.
Thank you for your fast response. I have found foggify.py in the plug-ins, and after some search in my german menu structur of GIMP3. But I have got the fear that it is not so easy to port my old scripts. In foggify.py for me it is not obvious at the first view, what happens, buy i will give it a try.
More hints and easier examples would be welcomed.
nelo March 31, 2025, 2:07pm 7
@Christoph_Raber,
you can download a “starter script” from here
unpack, put the scale_layer.py in a folder named scale_layer. Put that altogether in the plug-ins folder for GIMP.
When starting, it should produce a GIMP message.
I’ve placed your code as a comment into the right place. All you have to do now is to convert to GIMP3 terminology.
(Lots of comments left in the whole script, which of course can be deleted when production-ready.)
Hope that helps.
Hello Nelo, thank you very much, I now checked your adaption of my code, and it helped me really a lot.
Now I have a menu entry with the script and some outputs in the (error)consol of GIMP. But I am still struggeling with the translation of the C API to Python.
When I write
newWidth = 20
newHeight = 40
for layer in layers:
layerName=layer.get_name()
Gimp.message("layerName " + layerName)
layer.scale(newWidth, newHeight, FALSE)
the layerName is printed as expected but calling the “scale” interface produces an error. I tried different versions how to call the interface I found in the API reference
gimp_layer_scale ( GimpLayer* layer, gint new_width, gint new_height, gboolean local_origin)
but nothing had the expected result. Could you please support me here again?
Kind regards
Christoph
jboerema (Jacob Boerema) April 17, 2025, 9:42pm 9
Using False
instead of FALSE
should fix it.
My next question.
I try to call the filter “Enhance/Sharpen (Unsharp mask)” in my python script.
In the past (with Gimp2) I used the interface “pdb.plug_in_unsharp_mask()”,
but in Gimp3 I do not find this procedure/plugin, whenever it is available via the same menu.
How could I find the new name?
Kind regards
Christoph
nelo April 18, 2025, 2:38pm 12
That’s a GEGL filter now and goes like this:
f = Gimp.DrawableFilter.new(your_layer, "gegl:unsharp-mask", "")
filter_config = f.get_config()
filter_config.set_property('std-dev', 3.0) # radius
filter_config.set_property('scale', 0.25) # amount
filter_config.set_property('threshold', 0.0)
# your_layer.append_filter(f)
your_layer.merge_filter(f)
replace your_layer with the appropriate name, of course
PS.: you find GEGL operations here
https://gegl.org/operations/index.html
Hi Nelo,
again thank you for your fast and great support.
And also thank you for the link with the GEGL operations.
Where do I find information about “append/merge_filter”? Are there more such interfaces that could be or have to be used with the GEGL operations?
I will go on transform my scripts to the new interfaces. I hope it is ok if i will ask again, if there is the next question
Kind regards and a relaxing weekend
Christoph
Ofnuts April 18, 2025, 7:30pm 14
(search for “filter” in that page: 22 hits)
Some hints for inferring how Python works from that documentation: Converting the API doc to Python
Thank you for help, but there is the next problem I have got.
def generateBackgroundLayer(image, drawable, width, height):
Gimp.message("enter generateBackgroundLayer")
new_layer = image.layer_new ("Background", width, height, GIMP_RGB_IMAGE, 100, GIMP_LAYER_MODE_NORMAL_LEGACY)
image.insert_layer (new_layer, NULL, -1)
image.lower_item_to_bottom (new_layer)
Gimp.message("exit generateBackgroundLayer")
return
The call layer_new() is not working, what is wrong?
GimpLayer*
gimp_layer_new (
GimpImage* image,
const gchar* name,
gint width,
gint height,
GimpImageType type,
gdouble opacity,
GimpLayerMode mode
)
And is there a possiblity to debug something like this in a better way than only putting Gimp.messages() behind each line of code.
Kind regards
Christoph
nelo April 19, 2025, 5:45pm 16
This is my “template” for inserting new layers:
layer_new = Gimp.Layer.new(image,
"Name",
width,
height,
Gimp.ImageType.RGBA_IMAGE,
100.0,
Gimp.LayerMode.NORMAL)
image.insert_layer(layer_new, drawable.get_parent(), len(layers) + 1)
Instead of drawable.get_parent() you can also use None if there are no groups.
For debugging, I start GIMP from the terminal (I’m on Linux).
Then I can see what messages GIMP/ Python produces and normally see what the problem is.
April 19, 2025, 8:17pm 17
One thing that helps a lot in Gimp3 is using an IDE, and adding “types hints”. This gives you useful code completion while writing code and lots of problems are caught before you even try to execute the code(*).
On Linux at least, you can have the plugin execute under the Python built-in debugger. You just change the “shebang” from a regular call:
#!/usr/bin/env python3
to a version that invokes the debugger
#!/usr/bin/env -S python3 -m pdb
This may need to be refined because the debugger is invoked every time the code runs (registrations, and execution). And of course Gimp must be started from a terminal:
But I don’t know if:
- Gimp on Windows abides to the shebang or just says “ends in
.py
let’s launch Python” and in which case if this can be changed by hacking theinterpreters/default.interp
file - If you can interact with the debugger if the gimp-console.exe window.
Anyway, In practice, a CLI debugger is IMHO(**) not that much better than a couple of print instructions.
There may be a GUI debugger for Python on your OS somewhere, in which case it could just be a matter of changing the shebang. This would also be a solution on Linux and OSX.
(*) In Gimp2/Python v2.7, it usually took me 5-6 executions before the code even registered, due to various mistakes (bad function names, etc…). In Gimp3/python3.12 with an IDE, registration often works on first try.
(**) I learned programming before GUI IDEs were in fashion, so I could be biased.
Again thank you for your replay.
The line Gimp.Layer.new works, but the image.insert_layer now stops the execution of the plugin.
I am working on a Windows10 platform and there also with starting Gimp form command shell with “–verbose --stack-trace-mode=always --debug-handlers” does not show any errors. Only in the Warning window of Gimp I see that the plugin does not finish correctly.
Back to the call of Gimp.Layer.new. I thought that if I have got an object of type image or drawable, I could use one of its procedures to add a layer, instead of using something general like Gimp.Layer. But I think I not yet understand the object model of gimp.
Long writing, short message, I am still struggeling to add a layer to my image via python script. I hoped this is a very basic funtionality.
Hi Ofnuts, thank you for your support.
I am running gimp on a windows 10 platform. If I try to use a IDE like VSC, the code completion does not really work because it does not know the imported libs. If I try to install them via pip I struggle also with problems. So I think I have to work with printf, but sometimes that is a quite slow kind of working.
Ofnuts April 20, 2025, 9:39am 20
Normally no need to add them. You see may need to set up your Python path in the IDE to include the directories with the Python modules that come from Gimp.