Switch to full style
Post all Gimp scripts and script writing questions here
Post a reply

Calling a python script from a batch file

Sat Mar 04, 2017 7:32 pm

I've been wrestling with this one for some days now :yell. I've looked at other postings and they don't seem to offer an example of what I am trying to achieve:

I have a Windows 10 batch file ExportTaggedLayersToPNG.bat that contains:
Code:
"C:\Program Files\GIMP 2\bin\gimp-console-2.8.exe" --no-data --no-fonts --no-interface  "%~1"  -b "(python-fu-export-layers-as-png)" -b "(gimp-quit 0)"

python-fu-export-layers-as-png is the routine written by @paynekj and modified slightly to meet my needs. paynekj's routine works exactly as expected if I start Gimp, load an image and call the function from the menu entry that the plug-in registers. However, I want to call it from the command line in a batch file. As a first approximation, I called the Gimp console EXE with the command line above. The response I get is:
Code:
C:\PROJECTS\Images>"C:\Program Files\GIMP 2\bin\gimp-console-2.8.exe" --no-data --no-fonts --no-interface "Test.xcf" -b "(python-fu-export-layers-as-png)" -b "(gimp-quit 0)"

(gimp-console-2.8.exe:6888): LibGimpBase-WARNING **: gimp-console-2.8.exe: gimp_wire_read(): error
GIMP-Error: Unable to run plug-in "pcre3.dll"
(C:\Program Files\GIMP 2\lib\gimp\2.0\plug-ins\pcre3.dll)

Failed to execute child process (Exec format error)

GIMP-Error: Unable to run plug-in "bimp-uninstall.exe"
(C:\Program Files\GIMP 2\lib\gimp\2.0\plug-ins\bimp-uninstall.exe)

Failed to execute child process (Invalid argument)

GIMP-Error: Unable to run plug-in "bimp-locale"
(C:\Program Files\GIMP 2\lib\gimp\2.0\plug-ins\bimp-locale)

Failed to execute child process (No such file or directory)

GIMP-Error: Unable to run plug-in "Readme.txt"
(C:\Users\Ross\.gimp-2.8\plug-ins\Readme.txt)

Failed to execute child process (Exec format error)

GIMP-Error: Unable to run plug-in "Changelog.txt"
(C:\Users\Ross\.gimp-2.8\plug-ins\Changelog.txt)

Failed to execute child process (Exec format error)

GIMP-Error: Unable to run plug-in "autosave.cfg"
(C:\Users\Ross\.gimp-2.8\plug-ins\autosave.cfg)

Failed to execute child process (Exec format error)

batch command experienced an execution error:
Error: ( : 1) Invalid number of arguments for python-fu-export-layers-as-png (expected 2 but received 0)


which tells me (despite the flood of seemingly unrelated errors) that I can find the plug-in and call it successfully. I never expected the parameters to be correct because paynekj's routine expects parameters (only one from my reading of the code, but it's complaining about not getting the expected 2). So I believe I am real close now...

My questions:

- Why all the error messages when I start Gimp? It looks to me like it is trying to run all of the files in my plug-in folder as executables.

- What are the two parameters the routine is expecting? The declaration of the routine is:
Code:
...
# this is the bit that does all the work
def export_layers_as_png(img):
...

which suggests only one parameter might be expected.

- I deliberately introduced some bad syntax source code to see how errors are reported. I got:
Code:
batch command experienced an execution error:
Error: ( : 1) eval: unbound variable: python-fu-export-layers-as-png

which I guess points to a failure to compile that routine. Is there any way of getting error location a bit more precise?

- is there some method to the madness that seems to surround function naming? I see spaces, underscores, hyphens, a prepended "python-fu", but nowhere do I see the function referred to by the name given to it in the source.

I can live with the other quirks, but the main problem I have is the connection between the function call as passed with -b parameter in the batch file, and the function as declared in the .py file.

Re: Calling a python script from a batch file

Sun Mar 05, 2017 6:35 pm

1) On startup, Gimp checks all the executable files of the "plugins" directories. If the file is not registered or if its timestamp is not the one kept with the registration data ("pluginrc" file) then the file is executed to let it register. Gimp doesn't recall the plugins that didn't register so it retries them on each startup. And in Windows you can't tell what is executable and what is not (in OSX and Linux, files have an "executable" flag), so I assume it tries to run everything it finds. Maybe you should do bit of cleanup because bimp-uninstall.exe doesn't look like it belongs there (or is damaged).

2) The python routine expects an gimp.Image object (not an image file name...), which means it expect the image to be already loaded in Gimp. Now, Scheme plugins expect an INTERACTIVE/NON_INTERACTIVE first parameter which is hidden in Python plugins. This may explains why it complains about 2 while the routine need only one ("(python-fu-export-layers-as-png)" is actually Scheme code)

3) No because the "source code" is created on the fly from your batch arguments.

4) There is no madness but two different languages at play. In Scheme the "-" can be used in names of variables and functions (export-layers-as-png). In Python it is the subtraction operator and by convention in Python one uses underscores (export_layers_as_png). Then the function in Python is just a code object, which has no real name outside of Python. So to make it callable by Gimp (and Gimp scripts) a "Gimp name" is assigned to it. This "Gimp name" is given in the call to the "register()" function, which contains the Gimp name, a bunch of "meta-data" (copyright, description...), the parameters description, the name of the Python function, and the menu location. If the Gimp name doesn't start with "python-fu", the "python-fu-" prefix will be added to it. Makes more sense?

So your main problem is to load an image and pass it to the script... But I assume that if you are using a batch, you want to process many images, in which case you want something to iterate the images... And this can be done in Gimp. And if you are processing a single set of images, you can call the script from inside Gimp (and short-circuit all the command-line madness), give it a directory, and let it iterate the images in the directory. If you insist in using a command line batch, I attach sample batch I wrote a long time ago, which has the benefit of 1) showing how you iterate the files 2) be all-python, including the command line parameters.

Give it a good look (you are mostly interested in "batch.py" and "tgb.bat"), and come back with questions if needed.

Re: Calling a python script from a batch file

Mon Mar 06, 2017 4:37 pm

Very comprehensive answer @ofnuts. It must have taken a reasonable amount of time to put that together - many thanks. I'll have a play.

R
Post a reply