Posts: 20
Threads: 3
Joined: Sep 2024
Reputation:
0
Gimp version:
Operating system(s): Linux
Never mind abot the workflow files. I finally found that 'expot API' menu.
(10-30-2024, 06:14 PM)nchen Wrote: I appreciate you helping me with bug fixing 
I'm glad to help.
Posts: 27
Threads: 4
Joined: Sep 2024
Reputation:
2
Gimp version:
(11-01-2024, 12:33 AM)inkdolls Wrote: Okay, I know why the checkpoint was not being replaced: on line 26 of gp-generate-comfy-image.py, it says "CheckPointLoaderSimple" with a capital P in "Point", but the node is named "CheckpointLoaderSimple". Once I edited it, it runs fine. Understanding that part of the plugin was interesting.
I'll try to give you some more useful input about the workflow files. I realize now that modifying those is not very important for the basic stuff.
So for now I've just tested the "Generate-image" tool. Testing the others will probably take me some time. I'll get back to you if I run into other issues.
Ahh good to know! I just uploaded a fix that should make all node title searching non-case sensitive.
Posts: 20
Threads: 3
Joined: Sep 2024
Reputation:
0
Gimp version:
Operating system(s): Linux
Your change fixed it. I've been playing with this and there have been no more errors.
I'm still just learning. It's great not having to use a web browser. I've only tried the image generation and image to image. I don't use loras very much but those work well.
Looking at your files, you're using identical functions in many files. I don't know if you're aware that you can declare more than one plugin in one file calling register() repeatedly with different parameters for all the dialogs and a different function each time, so the basic code exists just once, making maintenance easier.
After more than a decade writing plugins, I learned that only quite recently.
Posts: 27
Threads: 4
Joined: Sep 2024
Reputation:
2
Gimp version:
(11-03-2024, 11:58 PM)inkdolls Wrote: Looking at your files, you're using identical functions in many files. I don't know if you're aware that you can declare more than one plugin in one file calling register() repeatedly with different parameters for all the dialogs and a different function each time, so the basic code exists just once, making maintenance easier.
After more than a decade writing plugins, I learned that only quite recently.
Thank you, that is very good to know! So essentially I just create one python file containing all of the plugins in a bundle?
I had tried creating classes for the plugins but it became too convoluted, so I'll definitely have to give this a shot. I just manually copied and pasted all of the functions in alphabetical order, for each plugin...
Hopefully things get a bit easier with GIMP 3 as well.
Posts: 6,666
Threads: 289
Joined: Oct 2016
Reputation:
587
Gimp version:
Operating system(s): Linux
(11-04-2024, 02:48 AM)nchen Wrote: (11-03-2024, 11:58 PM)inkdolls Wrote: Looking at your files, you're using identical functions in many files. I don't know if you're aware that you can declare more than one plugin in one file calling register() repeatedly with different parameters for all the dialogs and a different function each time, so the basic code exists just once, making maintenance easier.
After more than a decade writing plugins, I learned that only quite recently.
Thank you, that is very good to know! So essentially I just create one python file containing all of the plugins in a bundle?
I had tried creating classes for the plugins but it became too convoluted, so I'll definitely have to give this a shot. I just manually copied and pasted all of the functions in alphabetical order, for each plugin...
Hopefully things get a bit easier with GIMP 3 as well.
You can indeed register several plugins in a single Python file, but since 2.10 you can also do something else: put all your "common" code in a separate module
plug-ins
├── bar
│ ├── bar.py
│ └── libmodule.py
├── baz
│ ├── baz.py
│ └── libmodule.py
└── foo
├── foo.py
└── libmodule.py
- Each plugin in its own directory, together with all necessary files
- In such directories, Gimp only tries to register the executable that bears the same name as the directory, the other executables are ignored
- You of course distribute a copy of libmodule.py with each script, but given the size of python files the disk waste is minimal and you gain some upgrade independence
Posts: 27
Threads: 4
Joined: Sep 2024
Reputation:
2
Gimp version:
11-04-2024, 08:13 PM
(This post was last modified: 11-04-2024, 08:23 PM by nchen.)
(11-04-2024, 08:09 AM)Ofnuts Wrote:
- Each plugin in its own directory, together with all necessary files
- In such directories, Gimp only tries to register the executable that bears the same name as the directory, the other executables are ignored
- You of course distribute a copy of libmodule.py with each script, but given the size of python files the disk waste is minimal and you gain some upgrade independence
Thank you! That would save me a lot of time copying and pasting. I have been trying to implement this approach but I can't seem to get it to work.
Do the functions in the 'libmodule.py' have to be registered similar to the GIMP plugins, even though GIMP doesn't check them?
Also, are the input and output capabilities of functions within libmodule.py limited to GIMP's type codes (PF_INT, PF_FLOAT, etc)?
I have tried both registering them and not registering them to no avail.
For the example structure:
plug-ins
├── bar
│ ├── bar.py
│ └── libmodule.py
If I have a function within libmodule.py:
Code:
def insert_new_layer_with_alpha(image, width, height, name="New Layer"):
new_layer = pdb.gimp_layer_new(image, width, height, 0, name, 100, 28)
new_layer.add_alpha()
pdb.gimp_image_insert_layer(image, new_layer, None, 0)
return new_layer
register(
"python_fu_insert-new-layer-with-alpha", # Function Name
"Insert new layer with alpha channel", # Description
"Insert a new layer with an alpha channel", # Help
"user", # Author
"user", # Copyright
"11/4/2024", # Date Created
"insert...", # Menu label
"", # Image types
[
(PF_IMAGE, "image", "Image", None),
(PF_INT, "int", "Width", 0),
(PF_INT, "int", "Height", 0),
(PF_STRING, "string", "Layer name", "New Layer")
],
[
(PF_DRAWABLE, "new_layer", "New layer")
],
insert_new_layer_with_alpha, menu="<Image>/Comfy Tools")
Any time I attempt to import libmodule (with and without the register within libmodule.py), bar.py fails to register.
I have also tried registering and then calling insert_new_layer_with_alpha directly without importing.
I did test if the function within libmodule.py registers successfully to be sure it's not an error within the function.
The only time I've been able to get bar.py to register is when I don't attempt to import or call the functions within libmodule.py.
EDIT:
A kind of funny workaround I've been using sometimes is just installing a newer python version on my machine and calling it from the plugins:
Code:
import subprocess
input_data = data
# Run the script and pass the input data
process = subprocess.Popen(
["py", "path/to/script/python3script.py"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
stdout, stderr = process.communicate(input=input_data.encode('utf-8'))
result = stdout if process.returncode == 0 else stderr
Posts: 20
Threads: 3
Joined: Sep 2024
Reputation:
0
Gimp version:
Operating system(s): Linux
11-05-2024, 02:34 AM
(This post was last modified: 11-05-2024, 02:46 AM by inkdolls.)
Well, you got a more expert reply that I could have given.
I think the idea is that libmodule.py can contain functions common to many plugins so an exact copy works for all of them and registration should be left to smaller files matching the directory names.
From what I've read, Gimp 3 enforces that structure of plugin files in their own folders.
(11-04-2024, 02:48 AM)nchen Wrote: So essentially I just create one python file containing all of the plugins in a bundle?
I did that in the file I uploaded here. For me, it's convenient to pack two plugins in a small file.
And now I wonder if that will work in future Gimp versions.
Posts: 27
Threads: 4
Joined: Sep 2024
Reputation:
2
Gimp version:
(11-05-2024, 02:34 AM)inkdolls Wrote: Well, you got a more expert reply that I could have given..
I appreciate all input, as you're all legends for a newbie like myself
Separating out the plugins and using common libmodule files would help keep things organized.
Long term, I'd love to add a lot of free, ethical AI features to Gimp. Ai upscaling and ai gif/animations come to mind. I'm pretty close on an AI gif optimizer (since every frame in AI animations is unique due to diffusion, annoying to optimize).
Posts: 6,666
Threads: 289
Joined: Oct 2016
Reputation:
587
Gimp version:
Operating system(s): Linux
(11-04-2024, 08:13 PM)nchen Wrote: Thank you! That would save me a lot of time copying and pasting. I have been trying to implement this approach but I can't seem to get it to work.
Do the functions in the 'libmodule.py' have to be registered similar to the GIMP plugins, even though GIMP doesn't check them?
Also, are the input and output capabilities of functions within libmodule.py limited to GIMP's type codes (PF_INT, PF_FLOAT, etc)?
I have tried both registering them and not registering them to no avail.
For the example structure:
plug-ins
├── bar
│ ├── bar.py
│ └── libmodule.py
If I have a function within libmodule.py:
Code:
def insert_new_layer_with_alpha(image, width, height, name="New Layer"):
new_layer = pdb.gimp_layer_new(image, width, height, 0, name, 100, 28)
new_layer.add_alpha()
pdb.gimp_image_insert_layer(image, new_layer, None, 0)
return new_layer
register(
"python_fu_insert-new-layer-with-alpha", # Function Name
"Insert new layer with alpha channel", # Description
"Insert a new layer with an alpha channel", # Help
"user", # Author
"user", # Copyright
"11/4/2024", # Date Created
"insert...", # Menu label
"", # Image types
[
(PF_IMAGE, "image", "Image", None),
(PF_INT, "int", "Width", 0),
(PF_INT, "int", "Height", 0),
(PF_STRING, "string", "Layer name", "New Layer")
],
[
(PF_DRAWABLE, "new_layer", "New layer")
],
insert_new_layer_with_alpha, menu="<Image>/Comfy Tools")
Any time I attempt to import libmodule (with and without the register within libmodule.py), bar.py fails to register.
I have also tried registering and then calling insert_new_layer_with_alpha directly without importing.
I did test if the function within libmodule.py registers successfully to be sure it's not an error within the function.
The only time I've been able to get bar.py to register is when I don't attempt to import or call the functions within libmodule.py.
EDIT:
A kind of funny workaround I've been using sometimes is just installing a newer python version on my machine and calling it from the plugins:
Code:
import subprocess
input_data = data
# Run the script and pass the input data
process = subprocess.Popen(
["py", "path/to/script/python3script.py"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
stdout, stderr = process.communicate(input=input_data.encode('utf-8'))
result = stdout if process.returncode == 0 else stderr
If you use the Gimp API in the "libmodule" it should also do the required Gimp imports.
Posts: 1
Threads: 0
Joined: Apr 2025
Reputation:
0
Gimp version:
Operating system(s): Windows 11
(10-30-2024, 06:14 PM)nchen Wrote: (10-30-2024, 05:27 AM)inkdolls Wrote: Ok, thanks for your reply, I guess that works, but I already had managed to make it work before reading your post.
I found the last version of rgthree that still has the old node. Once I copied it, I finally got an image to appear in Gimp!
I've had a few hiccups though:
The checkpoint in the workflow overrides whatever I place in the dialog window in GImp. In fact, I initially got an error of 'Value not in list: ckpt_name: '1.5_dreamshaper_8.safetensors', since I don't have that model in my computer, it only worked when I manually edited the json file.
The Gimp plugin throws an error when reading json files that ComfyUI saves. I couldn't just save a modified workflow of yours, I had to manually edit the file.
Thanks a lot for this! This is going to be very useful. Sometimes I do a lot of back and forth between Gimp and Stable Diffusion. By the way, for anyone juggling multiple tasks like debugging, writing docs, or keeping content updated — I’ve been using Overchat AI lately. It’s been a game-changer for generating clean, structured text fast — super useful when time is short but quality still matters.
In regards to the checkpoint not working, are you supplying just the checkpoint name or the entire path? When selecting the file in the GIMP menu, it should provide the entire path. The way I currently have it, the code checks the provided path and selects just the file name at the end. Ultimately, just the name is necessary so this is an oversight on my part.
Another possibility: The code looks for the CheckPointLoaderSimple node (default checkpoint loader). Using another one might not work.
For the ComfyUI json files, you'll have to save as an API file. It should be one of the "save" options on the ComfyUI menu.
Also, I updated the files so it should work with the up-to-date rgthree power lora loader. I'll try to make the node options more flexible in the future.
You're welcome! Hopefully we can get it up and working smoothly for you. I appreciate you helping me with bug fixing 
Thanks for the clarification and update! That makes sense regarding the checkpoint path — I was indeed entering the full path instead of just the file name, so that might explain the issue. I’ll double-check if I’m using the default CheckPointLoaderSimple node too, as I may have swapped it out at some point while experimenting.
Good to know about saving the ComfyUI JSON files via the API option — I must have missed that in the menu. Appreciate you keeping things compatible with the latest rgthree updates as well. Looking forward to trying out the new version and seeing how things run now. Thanks again for your effort and responsiveness!
|