Posts: 16
Threads: 3
Joined: Mar 2021
Reputation:
0
Operating system(s):
Gimp version: 2.10
I have a working Gimp plugin that takes an open XCF, adds a new layer to it, positions the new layer, and then exports a JPG.
However, the plugin only works if I'm in the Gimp UI and the XCF file is already open. I want to run it from the command line and some how call pdb.gimp_xcf_load somewhere top open the XCF, but I can't get the file open or command line to work.
What is the best way to do this? Should I have a wrapper script that opens the XCF and then calls my working script? Or can I both open the XCF and the JPEG in a single plugin? Is there a best practice?
Posts: 301
Threads: 12
Joined: Oct 2016
Reputation:
16
Operating system(s):
- Windows (Vista and later)
Gimp version: 2.10
Is this the same plugin that I answered a question about on Stackoverflow?: https://stackoverflow.com/questions/6664...n-combined
If not, can you post the code you have so far. It should certainly be possible to do what you ask.
Posts: 16
Threads: 3
Joined: Mar 2021
Reputation:
0
Operating system(s):
Gimp version: 2.10
03-18-2021, 05:09 PM
(This post was last modified: 03-18-2021, 05:38 PM by TimorousMe.)
Hi Kevin. Yes that is me. My latest plugin is shown below. Everything works in the GIMP UI, but when I add my call for pdb.gimp_xcf_load(0, infileA, infileA) and introduce infileA into the definition and parameters, it fails.
I think there may be a problem because the image object isn't explicitly linked to my XCF or JPG. It would be great to avoid a file wrapper for opening the XCF, but if I need to I understand.
Below is my command line calls (two options I tried) and my plugin. These are the errors I get when I use these command line calls:
First command line call: "Error: eval: unbound variable: open_add_flatten_export"
Second command line call:
GIMP-Error: Failed to save data:
You have a writable data folder configured (/Users/TBradley/Library/Application Support/GIMP/2.10/gradients), but this folder does not exist. Please create the folder or fix your configuration in the Preferences dialog's 'Folders' section.
/Applications/GIMP-2.10.app/Contents/MacOS/gimp: GEGL-WARNING: (../../../../gtk/source/gegl-0.4.26/gegl/buffer/gegl-tile-handler-cache.c:1076):gegl_tile_cache_destroy: runtime check failed: (g_queue_is_empty (&cache_queue))
EEEEeEeek! 9 GeglBuffers leaked
To debug GeglBuffer leaks, set the environment variable GEGL_DEBUG to "buffer-alloc"
Quote:First command line call:
gimp -i -b '(open_add_flatten_export "/Users/TimB/Desktop/xcf_template.xcf" "/Users/TimB/Desktop/jpg_to_add.jpg" "2060" "410" "/Users/TimB/Desktop")' -b '(gimp-quit 0)'
Second command line call:
gimp -i --batch-interpreter python-fu-eval -b pdb.python_fu_open_add_flatten_export "/Users/TimB/Desktop/xcf_template.xcf" "/Users/TimB/Desktop/jpg_to_add.jpg" "2060" "410" "/Users/TimB/desktop" -b 'pdb.gimp_quit(0)'
Here's my plugin:
Code:
#!/usr/bin/env python
from gimpfu import *
def open_add_flatten_export(image, layer, infileA, infileB, x_offset, y_offset, outputFolder):
# Open XCF template
pdb.gimp_xcf_load(0, infileA, infileA)
try:
# Open file.
fileImage = None
if(infileB.lower().endswith(('.jpeg', '.jpg'))):
fileImage = pdb.file_jpeg_load(infileB, infileB)
# Create new layer.
newLayer = gimp.Layer(image, "New Layer Name", layer.width, layer.height, layer.type, layer.opacity, layer.mode)
# the +1 adds it behind the top layer
image.add_layer(newLayer, +1)
# Put image into the new layer.
fileLayer = fileImage.layers[0]
pdb.gimp_edit_copy(fileLayer)
floating = pdb.gimp_edit_paste(newLayer, True)
# Update the new layer.
newLayer.flush()
newLayer.merge_shadow(True)
newLayer.update(0, 0, newLayer.width, newLayer.height)
# Flatten + offset floating layer, then flatten image
pdb.gimp_floating_sel_to_layer(floating)
pdb.gimp_layer_set_offsets(floating, x_offset, y_offset)
pdb.gimp_image_flatten(image)
# Export JPG of flattened image
layer = pdb.gimp_image_get_active_layer(image)
pdb.file_jpeg_save(image, layer, outputFolder + "/" + "export.jpg", "raw_filename", 0.9, 0, 0, 0, "Creating with GIMP", 0, 0, 0, 0)
else:
gimp.message("The image could not be opened since it is not an image file.")
except Exception as err:
gimp.message("Unexpected error: " + str(err))
register(
"python_fu_open_add_flatten_export",
"Open XCF, add image to layer, flatten, and export",
"Open XCF, add image to layer, flatten, and export",
"Tim B.",
"Tim B.",
"2021",
"<Image>/Filters/Tim/Open, add, flatten, export",
"*",
[
(PF_FILE, "infileA", "XCF template", ""),
(PF_FILE, "infileB", "JPG to add", ""),
(PF_INT, "x_offset", "X offset", ""),
(PF_INT, "y_offset", "Y offset", ""),
(PF_DIRNAME, "outputFolder", "Output directory", ""),
],
[],
open_add_flatten_export)
main()
Posts: 301
Threads: 12
Joined: Oct 2016
Reputation:
16
Operating system(s):
- Windows (Vista and later)
Gimp version: 2.10
You have a mismatch between your command line and the code AND internally in the code.
The command line is trying to call open_add_flatten_save and the code is defining open_add_flatten_export
And in the register block you have the parameters infileA infileB x_offset y_offset outputFolder BUT the definition of the function is
image, layer, infileA, infileB, x_offset, y_offset, outputFolder
Also, you need assign image = pdb.gimp_xcf_load(infileA, infileA) and then find the active layer in image
As you're on MacOS, I can't be sure what your command line should look like, but Ofnuts will be along later to tell you what it needs to look like.
Posts: 6,356
Threads: 275
Joined: Oct 2016
Reputation:
565
Operating system(s):
Gimp version: 2.10
Btw, if you areusing the script only in batch, there is no need to register it as a plugin.
See https://stackoverflow.com/questions/4443...0#44435560
Posts: 16
Threads: 3
Joined: Mar 2021
Reputation:
0
Operating system(s):
Gimp version: 2.10
(03-18-2021, 05:30 PM)Ofnuts Wrote: Btw, if you areusing the script only in batch, there is no need to register it as a plugin.
See https://stackoverflow.com/questions/4443...0#44435560
Thanks guys. I didn't realize you had responded and I fixed some things in my initial post (including the mismatch) and also tried a different command line call before seeing your responses.
I will remove the definition and also assign image as Kevin suggests and I'll report back.
Posts: 16
Threads: 3
Joined: Mar 2021
Reputation:
0
Operating system(s):
Gimp version: 2.10
(03-18-2021, 05:40 PM)TimorousMe Wrote: (03-18-2021, 05:30 PM)Ofnuts Wrote: Btw, if you areusing the script only in batch, there is no need to register it as a plugin.
See https://stackoverflow.com/questions/4443...0#44435560
Thanks guys. I didn't realize you had responded and I fixed some things in my initial post (including the mismatch) and also tried a different command line call before seeing your responses.
I will remove the definition and also assign image as Kevin suggests and I'll report back.
I removed the definition part of my plugin as Ofnuts suggested, and then added the import language from the Stack Overflow post (as I cannot just call the function name now because it's not registered). I also followed Kevin's suggestion by assigning image = pdb.gimp_xcf_load(infileA, infileA) and then finding the active layer in image. The command line fails with the response below.
Plugin (renamed batch.py for simplicity)
Code:
#!/usr/bin/env python
import sys
from gimpfu import *
def open_add_flatten_export(infileA, infileB, x_offset, y_offset, outputFolder):
# Open XCF template
image = pdb.gimp_xcf_load(0, infileA, infileA)
layer = pdb.gimp_image_get_active_layer(image)
try:
# Open file.
fileImage = None
if(infileB.lower().endswith(('.jpeg', '.jpg'))):
fileImage = pdb.file_jpeg_load(infileB, infileB)
# Create new layer.
newLayer = gimp.Layer(image, "Added JPG", layer.width, layer.height, layer.type, layer.opacity, layer.mode)
# the +1 adds it behind the top layer
image.add_layer(newLayer, +1)
# Put image into the new layer.
fileLayer = fileImage.layers[0]
pdb.gimp_edit_copy(fileLayer)
floating = pdb.gimp_edit_paste(newLayer, True)
# Update the new layer.
newLayer.flush()
newLayer.merge_shadow(True)
newLayer.update(0, 0, newLayer.width, newLayer.height)
# Flatten + offset floating layer, then flatten image
pdb.gimp_floating_sel_to_layer(floating)
pdb.gimp_layer_set_offsets(floating, x_offset, y_offset)
pdb.gimp_image_flatten(image)
# Export JPG of flattened image
layer = pdb.gimp_image_get_active_layer(image)
pdb.file_jpeg_save(image, layer, outputFolder + "/" + "export.jpg", "raw_filename", 0.9, 0, 0, 0, "Creating with GIMP", 0, 0, 0, 0)
else:
gimp.message("The image could not be opened since it is not an image file.")
except Exception as err:
gimp.message("Unexpected error: " + str(err))
Command line command + arguments (modeled after Stack Overflow post)
Code:
gimp -idf --batch-interpreter python-fu-eval -b 'import sys;sys.path=['.']+sys.path;import batch;batch.run("/Users/TimB/Desktop/xcf_template.xcf" "/Users/TimB/Desktop/jpg_to_add.jpg" "2060" "410" "/Users/TimB/desktop")' -b 'pdb.gimp_quit(1)'
Response from command line:
Quote:GIMP is started as MacOS application
2021-03-18 21:10:18.605 gimp[2940:40051] *** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead.
/Applications/GIMP-2.10.app/Contents/MacOS/gimp: LibGimpBase-WARNING: gimp: gimp_wire_read(): error
gimp_check_updates_callback: loading of https://www.gimp.org/gimp_versions.json failed: Operation not supported
Traceback (most recent call last):
File "/Applications/GIMP-2.10.app/Contents/Resources/lib/gimp/2.0/python/gimpfu.py", line 827, in _run
return apply(func, params[1:])
File "/Applications/GIMP-2.10.app/Contents/Resources/lib/gimp/2.0/plug-ins/python-eval.py", line 25, in code_eval
exec code in globals()
File "<string>", line 1, in <module>
AttributeError: 'module' object has no attribute 'run'
batch command experienced an execution error
GIMP-Error: Failed to save data:
You have a writable data folder configured (/Users/TimB/Library/Application Support/GIMP/2.10/gradients), but this folder does not exist. Please create the folder or fix your configuration in the Preferences dialog's 'Folders' section.
Posts: 6,356
Threads: 275
Joined: Oct 2016
Reputation:
565
Operating system(s):
Gimp version: 2.10
- Your code doesn't define a run function but a open_add_flatten_export() one.
- I don't know how numeric arguments (your X, Y positions) are passed, you may receive them as string and have to explicitly convert them to int before using them.
- Not convinced that your copy/paste is going to work as it is, you are using plenty of calls that I have never used and they likely don't do what you think. The best way to copy a layer between the two images is to do a layer_copy = pdb.gimp_layer_new_from_drawable(fileImage.active_layer, image), and then do pdb.gimp_image_add_layer(image, layer_copy,1)
Posts: 16
Threads: 3
Joined: Mar 2021
Reputation:
0
Operating system(s):
Gimp version: 2.10
03-19-2021, 06:48 PM
(This post was last modified: 03-19-2021, 06:50 PM by TimorousMe.)
(03-19-2021, 08:18 AM)Ofnuts Wrote:
- Your code doesn't define a run function but a open_add_flatten_export() one.
- I don't know how numeric arguments (your X, Y positions) are passed, you may receive them as string and have to explicitly convert them to int before using them.
- Not convinced that your copy/paste is going to work as it is, you are using plenty of calls that I have never used and they likely don't do what you think. The best way to copy a layer between the two images is to do a layer_copy = pdb.gimp_layer_new_from_drawable(fileImage.active_layer, image), and then do pdb.gimp_image_add_layer(image, layer_copy,1)
Great advice from Ofnuts. It simplified my code (which I tested in the UI minus the file operation and it works great). My failure is either occuring because of how I try to open the XCF, or how I'm passing command line args. The command line seems to think it's getting 1 argument even though all 5 are listed. I tried other syntaxes, like comma delimited, semi-colon delimited, etc. Can you guys think of anything else to try?
Command line output:
Code:
Traceback (most recent call last):
File "/Applications/GIMP-2.10.app/Contents/Resources/lib/gimp/2.0/python/gimpfu.py", line 827, in _run
return apply(func, params[1:])
File "/Applications/GIMP-2.10.app/Contents/Resources/lib/gimp/2.0/plug-ins/python-eval.py", line 25, in code_eval
exec code in globals()
File "<string>", line 1, in <module>
TypeError: open_add_flatten_export() takes exactly 5 arguments (1 given)
batch command experienced an execution error
GIMP-Error: Failed to save data:
Command line arguments:
Code:
gimp -idf --batch-interpreter python-fu-eval -b 'import sys;sys.path=["."]+sys.path;import OAFE;OAFE.open_add_flatten_export("/Users/TimB/Desktop/xcftemplate.xcf" "/Users/TimB/Desktop/jpg_to_add.jpg" "2060" "410" "/Users/TimB/desktop")' -b 'pdb.gimp_quit(1)'
Plugin without definition, which I'm not using here. Filename is OAFE.py
Code:
#!/usr/bin/env python
import os, sys
from gimpfu import *
def open_add_flatten_export(infileXCF, infileJPG, x_offset, y_offset, outputFolder):
# Open XCF template
image = pdb.gimp_xcf_load(infileXCF, infileXCF)
drawable = pdb.gimp_image_get_active_layer(image)
# Load new JPG, and copy its contents into "layer_copy"
fileImage = None
fileImage = pdb.file_jpeg_load(infileJPG, infileJPG)
layer_copy = pdb.gimp_layer_new_from_drawable(fileImage.active_layer, image)
# Add layer_copy to XCF template, move it to desired position, and flatten
pdb.gimp_image_add_layer(image, layer_copy, 1)
pdb.gimp_layer_set_offsets(layer_copy, x_offset, y_offset)
pdb.gimp_image_flatten(image)
# Export JPG of flattened image
layer = pdb.gimp_image_get_active_layer(image)
pdb.file_jpeg_save(image, layer, outputFolder + "/" + "Export.jpg", "raw_filename", 0.9, 0, 0, 0, "Creating with GIMP", 0, 0, 0, 0)
Posts: 6,356
Threads: 275
Joined: Oct 2016
Reputation:
565
Operating system(s):
Gimp version: 2.10
Code:
OAFE.open_add_flatten_export("/Users/TimB/Desktop/xcftemplate.xcf" "/Users/TimB/Desktop/jpg_to_add.jpg" "2060" "410" "/Users/TimB/desktop")
This is indeed a single argument. If you want several arguments, you have to use commas (remember that everything between the single quotes is actually python source code, not shell code. Also if you put quotes around your number, they will be string args. Without quotes, they are likely to be the integers you need.
Code:
OAFE.open_add_flatten_export("/Users/TimB/Desktop/xcftemplate.xcf", "/Users/TimB/Desktop/jpg_to_add.jpg", 2060, 410, "/Users/TimB/desktop")
|