📜 ⬆️ ⬇️

How to write an add-on for GIMP in Python


Or is Script-Fu the so-called “mass filter”? Not everyone can deal with it, and most do not even try to make any plug-ins to GIMP.

RPG


Introduction


GIMP is a fairly powerful raster graphic editor with several advantages, one of which is the ability to extend functionality by writing add-ons.
')
Scheme and Python are suitable as languages ​​in which you can write add-ons. It is possible to write add-ons in other languages ​​(Perl, Tcl / Tk, etc.), but modules that implement this feature are poorly supported or do not work at all with fresh versions of GIMP .

If you choose the language for writing the Scheme add-on, you automatically win because there is no GIMP assembly in the world where the Scheme interpreter would not be included, and the addition you write will be guaranteed to work out of the box on all platforms, however, writing on Scheme is still fun ... Scheme is a LISP dialect. LISP is an abbreviation, stands for LIS t P rocessing, that is, a language for processing lists. There is another decoding: L anguage of I diotic S illy P arentheses (the language of idiotic stupid brackets), a controversial, but not without meaning, statement - failure to observe the balance of brackets is one of the main sources of program errors written in LISP and the like. Not everyone can deal with the difficult syntax of this language, and most do not even try to write any add-ons for GIMP . But complex syntax is a trifle compared to the lack of a number of possibilities. For example, you cannot use your own graphical interface, save add-on settings to a configuration file, connect some external module with additional functions, etc. etc. But there is a language that is devoid of most of the disadvantages of Scheme and has a number of advantages. This language is Python. About him and will be discussed.


PDB and Procedure Browser


GIMP provides us with an API that reflects all aspects of its management. For any action that can be performed with a mouse and keyboard, there is a corresponding API function. The set of API functions provided by GIMP forms the so-called PDB (The Procedural Database). To view the PDB, you need to use a special tool called the “Procedure Browser” and called by the “ View ... ” button from the FiltersPython-FuConsole window.



The “Procedure Browser” window is divided into two parts: the left side contains a list of available functions, the right one contains information about the currently selected function (name, brief description of actions performed, list of input and output parameters, information about the author, creation time and copyright ). The list is quite large (as I mentioned above, GIMP is a powerful graphical editor), but to make life easier, you can filter by the name (part of the name) of a function, by its brief description and by a number of other parameters that can be chosen from the drop-down list located on the right from the search bar.

Core modules


In order for our Python script to learn how to manage GIMP , pull the strings of its API , you need to connect the appropriate modules to it:

The source code of these modules can be found in the files located at: /usr/lib/gimp/2.0/python - if you are working in the GNU / Linux environment, or C: \ Program Files \ Gimp-2.7.5 \ lib \ gimp \ 2.0 \ python - if you are running on Windows.

Let's try?


So, I’ve talked about the “Browser Procedures” and the main modules; let's now try to manage GIMP via Python. To get started, start the Python-Fu console (recall: FiltersPython-FuConsole ).
You will see the following window:



The gimpfu module connects automatically when the console starts, so you need not worry about anything and immediately start entering commands.
To begin with, we will create a new image containing one layer of background color.



Be prepared for the fact that actions that produce functions are not always equivalent to actions that are performed interactively. When calling the appropriate command through the menu, for example, to create a new image, four steps are required, and in interactive mode this is done in one click (of course, the same four steps are performed, only they are hidden from the user).

The function for creating a new image is called gimp_image_new . The procedure browser tells us that it has three input parameters:

For the image type, there is a list of possible values ​​and the names of predefined constants that can be used instead of numbers for better readability of programs:

This function returns one parameter — the identification number (ID) of the newly created image (pointer to the image, if you like). Let's try to create a new RGB image with a size of 640x480 pixels. To do this, type the following at the command prompt:

>>> image = pdb.gimp_image_new(640, 480, RGB) >>> 


(Actually, it is not necessary to enter, just double-click on the name of the required function in the procedure browser window or select it and click the “Apply” button, after which the function template will be inserted into the console and all you have to do is enter the necessary parameters).

If after executing the command nothing was output, then GIMP successfully created the required image, and now we can access it through the variable image .

At the moment, the image consists only of an empty “canvas” and does not contain a single layer. The procedure browser tells us that you can create a new layer using the gimp_layer_new function, which has the following input parameters:

The "layer type" parameter (type) can take the following values:

This function returns the ID of the created layer. Create a new layer:

 >>> layer = pdb.gimp_layer_new(image, 640, 480, RGB_IMAGE, "", 100, NORMAL_MODE) >>> 


If nothing has been output, then a new layer named “Background” has been successfully created, and we can access it through the variable layer .

Now you need to embed the layer in the image. This is done using the gimp_image_insert_layer function. According to the procedure browser, this function has four input parameters:

It is important to remember that the layer type must match the image type, in other words, do not try to insert the GRAY layer into the RGB image.

In our case, we need to embed the layer in the image , placing it on the lower (zero) level:

 >>> pdb.gimp_image_insert_layer(image, layer, None, 0) >>> 


Now, in order for the new layer to acquire the background color, it must be cleared (if this is not done, the layer will be foreground color) using the gimp-edit-clear function, which has only one input parameter:
drawable - an area available for drawing.
drawable is a rather interesting parameter. Unlike image, which is always an image, or width, which is always width, drawable can be a layer, a selected area or a channel, depending on which object this or that function works with, in this case, gimp-edit-clear as a parameter, pass a pointer to the layer).

The effect produced by the gimp_edit_clear function depends on the layer type: the layer containing the alpha channel will become transparent as a result of the cleaning, and the RGB layer will be filled with the background color.

Clear the layer :

 >>> pdb.gimp_edit_clear(layer) >>> 


The new image is ready, now you can display it:

 >>> display = pdb.gimp_display_new(image) >>> 


The gimp_display_new function creates a new window on the screen and displays an image in it, the ID of which is passed to it as a parameter. This function returns the window ID.
As a result of the manipulations, a tab should appear on the screen containing an RGB image, 640x480 pixels in size, consisting of one layer, which is filled with the background color.



So. We can now manage GIMP via API functions. How do these manipulations form in the form of a Python-script? About this below.

"Skeleton" additions


A typical addition written using the gimpfu module is as follows:

 #!/usr/bin/env python # -*- coding: utf-8 -*- #    from gimpfu import * #   def plugin_func(image, drawable, args): # #    : #      # #    PDB register( "python-fu-plugin-func", #    "-   ", #    " -  -, -  -", #      " ", #    "  (author@server.ru)", #    (?) "8.01.2012", #   " ", #   ,       "*", #  ,      [ (PF_IMAGE, "image", " ", None), # ,     (PF_DRAWABLE, "drawable", " ", None),#    ,   .. (PF_STRING, "arg", "The argument", "default-value") ], [], #  ,    plugin_func, menu="<Image>//") #     ,     ,   #   main() 

Let us dwell in more detail on the function that registers our supplement in the PDB. Pay attention to the python-fu prefix. In general, this is a rule of good tone - to give names to functions by their belonging and by the action they perform, so that by the name of the function it is clear what to expect from it. If the function name starts with the word “gimp” is the “native” function of GIMP , “plug-in” are usually compiled add-ons written in C (most likely filters), “script-fu” are extensions written in Scheme, "Python-fu" - as you probably already guessed - extensions written in Python-e.

The names also contain an indication of the object with which the function works, for example, if you need to do something with layers, you should look for the necessary function in the PDB by specifying “layer” in the search bar to find functions that work with selected areas - “select " etc. In addition, if you do not specify the prefix “python-fu” at the beginning of the function, then it will not be registered (in my opinion, this is only a restriction for Python scripts, and it is for the best, I think).

Also note that all the underscore "_" in the name of the registered function must be replaced with the sign "-" - this ambiguous feature spoiled a lot of blood for me when I began to master the writing of additions to Pythone. I do not fully understand why this was done, but otherwise the supplement simply does not work ...

The parameter of the register () function, which is responsible for specifying the type of image with which the add-on will work, can have the following values: RGB, RGBA, GRAY, GRAYA, INDEXED. To specify all types of RGB and shades of gray, you can use "*" like this: RGB *, GRAY *. If the addition is for all types of images, then you can simply specify "*". This parameter also affects the activity of the menu item that launches the add-on. For example, if your add-on works only with RGB images, and you have an open image representing only shades of gray, the menu will be inactive. In turn, if you specify “*” as the image type, the menu will be active, even if no image is currently open (a useful hack, when there is a need to generate an image from scratch, and not to edit the finished one).

Less words, more code


Let's move from words to deeds. Let's write a simple demo supplement that will draw a frame of a given size and color around the image. To do this, take the supplement skeleton mentioned above and enter the necessary code in it.

 #!/usr/bin/env python # -*- coding: utf-8 -*- #    from gimpfu import * def add_colored_border(image, drawable, border_width, border_color): pdb.gimp_context_push() #      , #            #  Ctrl + Z     ""  " " pdb.gimp_image_undo_group_start(image) #         pdb.gimp_image_resize(image, pdb.gimp_image_width(image) + border_width, pdb.gimp_image_height(image) + border_width, border_width / 2, border_width / 2) #   . #     : #        old_background = pdb.gimp_context_get_background() #    pdb.gimp_context_set_background(border_color) #   pdb.gimp_image_flatten(image) #       pdb.gimp_context_set_background(old_background) #     pdb.gimp_displays_flush() #       pdb.gimp_image_undo_group_end(image) pdb.gimp_context_pop() #    PDB register( "python-fu-add-colored-border", #    "    ", #    "        ", #      " ", #    "  (zend.karabanov@gmail.com)", #    (?) "8.01.2012", #   " ", #   ,       "*", #        [ (PF_IMAGE, "image", " ", None), #    (PF_DRAWABLE, "drawable", " ", None), #    (PF_INT, "border_width", " ", "10"), #   (PF_COLOR, "border_color", " ", (39,221,65)) #   ], [], #      add_colored_border, menu="<Image>//") #             #   main() 


Now save this code to the file add_colored_border.py , for example, and copy it into the folder with the additions.
If you are working in a GNU / Linux environment, then this folder will be ~ / .gimp-2.xx / plug-ins / (do not forget to give your script permissions to execute).

Windows users need to place the add-on in the % USERPROFILE% \. Gimp-2.xx \ plug-ins \ folder (For more information on installing add-ons, see the free GIMP graphic editor on the official Russian-language website on Installing Add-ons in GIMP ).

Launch GIMP and look at the menu bar. If you did everything right, then next to the Filters menu appeared the TEST menu, from which you can launch our add-on.



And in PDB, a new procedure, python-fu-add-colored-border, has appeared .



Try the addition in action. To do this, create a new image, call our add-on from the menu TESTAdd frame . A dialogue like this will appear:



As you can see, GIMP itself took care of the graphical interface, and we did not have to do the dirty work, arranging text fields and buttons on the form of the dialog box, but we are not able to influence the appearance of this dialog. Next time, I'll tell you how to get rid of these flaws and unleash all the power of Python in relation to the GIMP -a add-ons.

In the meantime, select the width of the frame, its color and click " OK ". Our addition will work, and you will see approximately the following result:



useful links


Source: https://habr.com/ru/post/135863/


All Articles