GIMP on Windows – executing a python-fu script from the command line

Question:

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 FilesGIMP 2bingimp-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?

Asked By: Tfb9

||

Answers:

From my Windows archives:

gimp -idf -b "yourscript" -b "pdb.gimp_quit(1)"
Answered By: xenoid

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

“C:Program FilesGIMP 2bingimp-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
Answered By: Tfb9

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 FilesGIMP 2bingimp-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 FilesGIMP 2libgimp2.0plug-insfile-rawtherapeefile-rawtherapee.exe’
Initializing plug-in: ‘C:Program FilesGIMP 2libgimp2.0plug-insfile-heiffile-heif.exe’
Initializing plug-in: ‘C:Program FilesGIMP 2libgimp2.0plug-insfile-darktablefile-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:UserssebasAppDataRoamingGIMP2.10colorrc’
Writing ‘C:UserssebasAppDataRoamingGIMP2.10templaterc’
Writing ‘C:UserssebasAppDataRoamingGIMP2.10parasiterc’
Writing ‘C:UserssebasAppDataRoamingGIMP2.10unitrc’
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.

Answered By: Sebastian