GIMP on Windows - executing a python-fu script from the command line
Asked Answered
P

3

6

In a Windows environment, I would like to make a call to GIMP for executing a python-fu script (through a BAT file) but the command line call I am using does not produce the expected results.

For example, consider the following python-fu script named makeafile_and_quit.py, which rerside in my GIMP's plug-ins folder. Its purpose is to load an existing image and save under a different name:

#!/usr/bin/env python

# Sample call from GIMP's python-fu console:
# pdb.python_fu_makeafile_and_quit_script()

from gimpfu import *

def makeafile_and_quit( ) :

    FILEPATH   = 'C:\\path\\to\\file.JPG'
    IMAGE      = pdb.gimp_file_load( FILEPATH,  FILEPATH )

    pdb.gimp_file_save( IMAGE, pdb.gimp_image_get_active_drawable( IMAGE ), FILEPATH + '_2.jpg',  FILEPATH + '_2.jpg' )

    pdb.gimp_quit(0)

    return


# PLUGIN REGISTRATION
# This is the plugin registration function
register(
    'makeafile_and_quit_script',
    'v0.0',
    'A new concept',
    'Author',
    'Author',
    'Just now',
    '<Toolbox>/MyScripts/This will make a file and _QUIT',
    '',
    [],
    [],
    makeafile_and_quit
    )

main()

The script executes flawlessly if called from a 'GUI instance' of GIMP, calling the script through the menus. It produces a new file ending with '_2.jpg' in the same folder as the source file.

The behaviour is different when called from the command prompt using the following:

"C:\Program Files\GIMP 2\bin\gimp-2.8.exe" --batch '("makeafile_and_quit.py")' -b "(gimp-quit 0)"

An instance of GIMP is created, then, closes but no file is created even though the message batch command executed successfully is seen.

How can I repeat exactly the same behaviour as a 'GUI instance', from the command line?

Pest answered 1/2, 2017 at 1:11 Comment(7)
taskkill does not get called because gimp-2.8.exe never fully closes and return control. If I CTRL-C to interrupt GIMP, it closes and taskkill finally executes but it returns an error (process cannot be found). Killing the task after supposed completion of the script is not what I am looking for.Pest
I think I missed a -b before the '(gimp-quit 0)' so I just added that to the above comment in case that makes any difference.... so "C:\Program Files\GIMP 2\bin\gimp-2.8.exe" --no-interface --batch '("just_quit.py")' -b '(gimp-quit 0)'Vachil
When you're done testing, let me know how it goes... from what I read you do not need to specify --batch-interpreter=python-fu-eval since that's usually the default so I left that out of the comments. Additionally I didn't see that you have to use the execfile either so I left that out too. The main thing though was to add the additional -b '(gimp-quit 0)' to close out of the previous console from what I read about. So you can probably just add that to your existing script and perhaps it'll work just by adding that...not sure about the other things I noted which I omitted from my exampleVachil
@Pest Is it significant that you've got a trailing comma after the last argument of your register() directive? Just a guess, but I bet that shouldn't be there.Katonah
Great! Let me know how it goes and if you want me to add an answer once you confirm.Vachil
@Katonah Very nice catch - now that is fixed but I am not sure of my progress about calling scripts programmatically.Pest
@Walmart The just_quit script appears fine, in that: with one more keystroke I can get back at the original prompt. However when pointing at my full-size script (which works fine when called through the GUI), the script has not produced the files it was supposed to, so I am investigating that.Pest
P
5

After much fiddling, I arrived at the following command which works as desired:

"C:\Program Files\GIMP 2\bin\gimp-console-2.8.exe" --verbose --batch "(python-fu-makeafile-and-quit-script RUN-NONINTERACTIVE)" --batch "(gimp-quit 0)"

Take care to:

  • use gimp-console-2.8.exe instead of gimp-2.8.exe to avoid unnecessary keystroke at the end of execution
  • prefix the function name with python-fu-
  • use -'s instead of _'s in names
  • add the generic (and necessary) RUN-NONINTERACTIVE argument
  • in your script, do not use functions calling displays, such as DISPLAY = gimp.Display( IMAGE ), which make the script fail with gimp-console-2.8.exe
Pest answered 2/2, 2017 at 2:24 Comment(0)
R
0

From my Windows archives:

gimp -idf -b "yourscript" -b "pdb.gimp_quit(1)"
Redneck answered 1/2, 2017 at 7:52 Comment(0)
R
0

it's been a while. Nevertheless i want to do the same thing. The difference is, that my script in pyhton is using two variables.

import os
from gimpfu import *

## The image has to be manually opened in gimp.
## under File -> Crop and Merge the Script can be executed
## The file is safed in the same location in an subdirectory that can be changed in the script below

dir_name = '\\Homepage\\'

def my_function(image, drawable):
    # define variables
    drawable = pdb.gimp_image_get_active_drawable(image)
    width = float(pdb.gimp_image_width(image))
    height = float(pdb.gimp_image_height(image))
    image_duplicate = pdb.gimp_image_duplicate(image)
    aspect_ratio = 1520./980.
    watermark_file = "F:\Vorlage_Homepage_1520x980.png"
    counter = 1
    img_file = pdb.gimp_image_get_filename(image)
    img_path = os.path.dirname(img_file)
    print (img_path)

    #checking, if a subdirectory exists
    check_path = img_path + dir_name
    exist = os.path.exists(check_path)
    if not exist:
        os.makedirs (check_path)

    #checking, if file(s) already exists
    exists = 1
    while exists:
        if os.path.exists(check_path + os.path.basename(os.path.dirname(img_file)) + '_' + str(counter) + '.jpg'):
            counter += 1
        else:
            exists = 0

    export_name = check_path + os.path.basename(os.path.dirname(img_file)) + '_' + str(counter) + '.jpg'
    print (export_name)    

    if width/height > aspect_ratio:
        # crop the image centerd by width
        new_width = height * aspect_ratio
        off_x = int((width - new_width) / 2)
        pdb.gimp_image_crop(image_duplicate, int(new_width), int(height), off_x, 0)
    else:
        # crop the image centerd by height
        new_height = width / aspect_ratio
        off_y = int((height-new_height) / 2)
        pdb.gimp_image_crop(image_duplicate, int(width), int(new_height), 0, off_y)

    # Scaling the image
    pdb.gimp_image_scale(image_duplicate, 1520, 980)

    # add the watermark
    layer_to_add = pdb.gimp_file_load_layer(image_duplicate, watermark_file)
    pdb.gimp_image_add_layer(image_duplicate, layer_to_add, 0)

    # merge layers
    merged_layer = pdb.gimp_image_merge_visible_layers(image_duplicate, 2)
    pdb.gimp_image_set_active_layer(image_duplicate, merged_layer)
    pdb.file_jpeg_save(image_duplicate, merged_layer, export_name, export_name, 0.85, 0, 1, 1, "", 0, 1, 0, 0)



register(
    "python_fu_my_function",  # Name of the function
    "Crop and Merge",  # Description of the function
    "Crops and scales the image, aftwards give it a watermark",  # Help text
    "Sebastian Knab",  # Author
    "Sebastian Knab",  # Copyright
    "2023",  # Creation date
    "<Image>/File/Crop and Merge",  # Menu location
    "*",  # Image type
    [],  # Input parameters
    [],  # Return values
    my_function,  # The function to register
)

main()

The code works fine in gimp. Interesting is that I have to use drawable, even I don't use it. But if i want to call it via a .bat script nothing happens, with --verbose I don't get an error, just the hint that the default interpreter is used.

setlocal enabledelayedexpansion
set "photo=F:\DSC0352.jpg"
set "gimp=C:\Program Files\GIMP 2\bin\gimp-console-2.10.exe"


    "%gimp%"  --verbose --batch python-fu-eval "(python-fu-my-function '!photo!' 'None')" --batch "(gimp-quit 0)"
    

Here is what I get in the .log file:

Initializing plug-in: 'C:\Program Files\GIMP 2\lib\gimp\2.0\plug-ins\file-rawtherapee\file-rawtherapee.exe' Initializing plug-in: 'C:\Program Files\GIMP 2\lib\gimp\2.0\plug-ins\file-heif\file-heif.exe' Initializing plug-in: 'C:\Program Files\GIMP 2\lib\gimp\2.0\plug-ins\file-darktable\file-darktable.exe' Starting extension: 'extension-script-fu' No batch interpreter specified, using the default 'plug-in-script-fu-eval'. batch command executed successfully EXIT: gimp_exit EXIT: gimp_real_exit Writing 'C:\Users\sebas\AppData\Roaming\GIMP\2.10\colorrc' Writing 'C:\Users\sebas\AppData\Roaming\GIMP\2.10\templaterc' Writing 'C:\Users\sebas\AppData\Roaming\GIMP\2.10\parasiterc' Writing 'C:\Users\sebas\AppData\Roaming\GIMP\2.10\unitrc' EXIT: app_exit_after_callback edit new file or finish

Of course i tried a lot with the arguments by calling the gimp-console-2.10.exe. After a lot hours i thought maybe someone can help. It also doesn't help to run the .bat with admin rights. The images are not saved. I also tried the syntax form this site.

"%gimp%" --verbose --batch-interpreter python-fu-eval -b "import sys;sys.path=['.']+sys.path;import script;script.einser('!image_file!', '!image_file!')" -b "pdb.gimp_quit(1)"

I tried the second argument with 'None' or '', also used " instead of ', but this had no influence.

Rema answered 29/1, 2023 at 14:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.