Ve třetí části článku o tvorbě pluginů určených pro známý bitmapový grafický editor GIMP si ukážeme, jakými způsoby je možné naprogramovat konfigurovatelný přídavný modul (plugin), který po svém spuštění vytvoří nový obrázek s vykreslenou hvězdnou oblohou. Jednotlivé verze pluginu budou paralelně vytvářeny jak v programovacím jazyce Scheme (jde o technologii nazvanou Script-fu), tak i v populárnějším a používanějším Pythonu (technologie pojmenovaná Python-fu).

Obsah

1. Tvorba pluginů pro grafický editor GIMP (3.část – vykreslení hvězdné oblohy)

2. Jednoduchá hvězdná obloha – verze naprogramovaná ve Scheme

3. Přepis prvního pluginu do Pythonu

4. Vykreslení hvězd s využitím aktuálně nastavené tužky

5. Varianta druhé verze pluginu naprogramovaná ve Scheme

6. Varianta druhé verze pluginu naprogramovaná v Pythonu

7. Výběr štětce s nastavením velikosti jeho stopy

8. Varianta třetí verze pluginu naprogramovaná ve Scheme

9. Varianta třetí verze pluginu naprogramovaná v Pythonu

10. Proměnná a konfigurovatelná velikost hvězd

11. Varianta čtvrté verze pluginu naprogramovaná ve Scheme

12. Varianta čtvrté verze pluginu naprogramovaná v Pythonu

13. Přidání druhé vrstvy s rozmazanými hvězdami

14. Varianta páté verze pluginu naprogramovaná ve Scheme

15. Repositář s demonstračními příklady

16. Odkazy na Internetu

1. Tvorba pluginů pro grafický editor GIMP (3.část – vykreslení hvězdné oblohy)

Na předchozí dvě části článku o tvorbě pluginů určených pro bitmapový grafický editor GIMP [1] [2] dnes navážeme, protože v několika krocích naprogramujeme konfigurovatelný zásuvný modul (plugin), který po svém spuštění vytvoří nový bitmapový obrázek a posléze v tomto obrázku vykreslí hvězdnou oblohu. První verze pluginu bude velmi jednoduchá, poslední (konkrétně pátá) verze pak již poměrně sofistikovaná, protože se v ní budou používat další filtry (rozmazání, normalizace) dostupné v každé instalaci GIMPu a nakonec se nevyhneme ani nutnosti manipulace s hladinami (layers).

Pro začátek si připomeňme, že pluginy pro grafický editor GIMP je možné vytvářet buď v programovacím jazyce Scheme s využitím technologie pojmenované Script-fu, nebo v Pythonu (v tomto případě jde o technologii nazvanou Python-fu). V rámci porovnání syntaxe i sémantiky obou zmíněných jazyků bude plugin paralelně vytvářen jak ve Scheme, tak i v Pythonu. Funkčně by se v obou případech mělo jednat o prakticky totožný plugin jen s nepatrně odlišným chováním.

Obrázek 1: Ukázka poměrně jednoduchého demonstračního příkladu popsaného v předchozí části tohoto článku.

2. Jednoduchá hvězdná obloha – verze naprogramovaná ve Scheme

První verze pluginu určeného pro vytvoření hvězdné oblohy bude prozatím velmi jednoduchá. Funkce, která hvězdnou oblohu vytvoří, bude akceptovat tři parametry: šířku obrázku, výšku obrázku a celkový počet hvězd, které se mají vykreslit. Všechny parametry se budou nastavovat z dialogu pluginu, který vypadá následovně:

Obrázek 2: Konfigurační dialog první verze pluginu pro vykreslení hvězdné oblohy.

Deklarace konfiguračního dialogu z předchozího obrázku může vypadat takto:

(script-fu-register "script-fu-stars-1"
                    "<Image>/Filters/Render/Pattern/Stars1"
                    "Vytvori obrazek hvezdnou oblohou."
                    "Pavel Tisnovsky"
                    "Pavel Tisnovsky"
                    "2017-04-17"
                    ""
                    SF-ADJUSTMENT "Image width"  '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Image height" '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Stars"        '(250 10 2000 10 20 0 1)
)

Zavolaná funkce nazvaná script-fu-stars-1 postupně provede následující kroky:

  1. Vytvoří nový obrázek typu RGB (Red, Green, Blue) s nastavenou šířkou a výškou zadanou prvními dvěma parametry.
  2. Vytvoří hladinu nazvanou „Stars“, která má stejné rozměry, jako obrázek (teoreticky se mohou rozměry hladiny lišit od rozměrů obrázku).
  3. Tuto hladinu vloží do obrázku na nultou pozici (hladiny se ukládají nad sebe do jakéhosi zásobníku).
  4. Deklaruje tříprvkové pole bajtů sloužící pro uložení RGB barvy hvězd.
  5. Nastaví barvu pozadí (tmavě modrá) a vyplní hladinu „Stars“ touto barvou.
  6. V programové smyčce vykreslí hvězdy na náhodné pozice. Každá hvězda je vykreslena jediným žlutým pixelem.

Programová smyčka, v níž se vykreslí hvězdy, vypadá takto:

(do ((i 0 (+ i 1)))
    ((= i stars))
    (let* (
       (x (rand width))
       (y (rand height)))
       ; vykreslení žlutého pixelu/hvězdy
       (gimp-drawable-set-pixel layer x y 3 pixel))
) ; end of loop

Poznámka: správně by se poslední uzavírací závorka měla psát za volání funkce gimp-drawable-set-pixel.

Podívejme se nyní na zdrojový kód funkce script-fu-stars-1. Nejsložitější částí skriptu je programová smyčka, která se v programovacím jazyku Scheme dá vytvořit buď makrem pojmenovaným repeat (toto makro však většinou není ve Script-fu dostupné), iterací s takzvanou tail call optimalizací (TCO) nebo s využitím takzvané speciální formy do. Vlastní vykreslení hvězd se provádí funkcí gimp-drawable-set-pixel, kterou již známe z předchozích částí článku:

; Funkce, která vytvoří nový obrázek o zadané velikosti.
; V obrázku bude jedna hladina nazvaná "Stars" a
; v této hladině bude vykreslena hvězdná obloha.
(define (script-fu-stars-1 width height stars)
    ; definice lokálních proměnných
    (let*
        (
            ; vytvoření nového obrázku, jehož ID se uloží
            ; do proměnné nazvané "image"
            (image (car (gimp-image-new width height RGB)))
            ; vytvoření nové hladiny, jejíž ID se uloží
            ; do proměnné nazvané "layer"
            (layer (car (gimp-layer-new image width height RGB-IMAGE "Stars" 100 NORMAL-MODE)))
            ; pole s uloženými RGB hodnotami pixelu
            (pixel (cons-array 3 'byte)))

        ; barva vykreslovanych hvezd
        (aset pixel 0 255)
        (aset pixel 1 255)
        (aset pixel 2 50)

        ; zákaz ukládání operací do zásobníku
        (gimp-image-undo-disable image)
        ; přidání hladiny do vytvořeného obrázku
        (gimp-image-add-layer image layer 0)

        ; změna barvy popředí a pozadí
        (gimp-palette-set-foreground '(255 255 255))
        (gimp-context-set-background '(0 0 40))

        ; vyplnění hladiny konstantní barvou
        (gimp-drawable-fill layer 1)  ;0 FG, 1 BG

        (do ((i 0 (+ i 1)))
            ((= i stars))
            (let* (
               (x (rand width))
               (y (rand height)))
               ; vykreslení žlutého pixelu/hvězdy
               (gimp-drawable-set-pixel layer x y 3 pixel))
        ) ; end of loop

        ; zobrazení právě vytvořeného obrázku
        (gimp-display-new image)

        ; povolení ukládání operací do zásobníku
        (gimp-image-undo-enable image)))

; Registrace skriptu do prostředí grafického editoru GIMP
; a specifikace proměnných nastavitelných uživatelem,
; které se posléze přenesou jako parametry skriptu.
(script-fu-register "script-fu-stars-1"
                    "<Image>/Filters/Render/Pattern/Stars1"
                    "Vytvori obrazek hvezdnou oblohou."
                    "Pavel Tisnovsky"
                    "Pavel Tisnovsky"
                    "2017-02-19"
                    ""
                    SF-ADJUSTMENT "Image width"  '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Image height" '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Stars"        '(250 10 2000 10 20 0 1)
)

Obrázek 3: Prozatím velmi primitivní hvězdná obloha vykreslená první verzí pluginu.

3. Přepis prvního pluginu do Pythonu

Přepis první verze pluginu z programovacího jazyka Scheme do dnes populárnějšího Pythonu vlastně není nijak složitý. Zkombinujeme zde dva přístupy – vytváření nových objektů (obrázek, hladina) s využitím konstruktorů gimpfu.gimp.Image() a gimpfu.gimp.Layer() a přístup k již existujícím „GIMPovským“ objektům přes takzvanou pdb neboli procedural database. To se týká především volání funkce gimp_drawable_set_pixel(), což je vlastně stejná funkce, jako výše zmíněná (gimp-drawable-set-pixel). Ovšem programovací jazyk Python neumožňuje používat ve jménech funkcí znak pomlčky, takže je nutné všechny pomlčky nahradit za podtržítka (totéž ostatně platí i pro všechny další identifikátory, včetně jmen parametrů funkcí, jmen proměnných, názvů modulů atd.).

Rozdíly ve volání funkcí použitých v našem skriptu ve stručnosti shrnuje následující tabulka:

Funkce ve Scheme Volání v Pythonu
(gimp-image-new) gimp.Image()
(gimp-layer-new) gimp.Layer()
(gimp-image-add-layer) image.add_layer()
(gimp-drawable-fill) layer.fill()
(gimp-drawable-set-pixel) pdb.gimp_drawable_set_pixel()
(gimp-display-new) gimp.Display()

Navíc si povšimněte, že se barva pixelu specifikuje n-ticí (tuple), což je mnohem jednodušší a dokonce i čitelnější, než v případě programovacího jazyka Scheme:

pdb.gimp_drawable_set_pixel(layer, x, y, 3, (255, 255, 50))

Programová smyčka vykreslující hvězdy se taktéž částečně zjednodušila:

for i in range(int(stars)):
    # pozice hvezdy v obrazku
    x = randint(0, int(width)-1)
    y = randint(0, int(height)-1)
    # vykresleni jedne hvezdy do obrazku
    pdb.gimp_drawable_set_pixel(layer, x, y, 3, (255, 255, 50))

Zdrojový kód první verze pluginu přepsaného do programovacího jazyka Python vypadá následovně:

#!/usr/bin/env python

from gimpfu import *
from random import *

# funkce zavolana po spusteni pluginu uzivatelem
def create_starry_sky_1(width, height, stars):
    # vytvoreni noveho obrazku
    image = gimp.Image(int(width), int(height), RGB);

    # vytvoreni nove hladiny
    layer = gimp.Layer(image, "Stars", int(width), int(height), RGB_IMAGE, 100, NORMAL_MODE)

    # nastaveni barvy vykreslovani pozadi (druha barva ve vyberu)
    gimp.set_background(0, 0, 40)

    # vyplneni hladiny konstantni barvou
    layer.fill(BACKGROUND_FILL)

    # pridani hladiny do zasobniku hladin v obrazku
    image.add_layer(layer, 0)

    for i in range(int(stars)):
        # pozice hvezdy v obrazku
        x = randint(0, int(width)-1)
        y = randint(0, int(height)-1)
        # vykresleni jedne hvezdy do obrazku
        pdb.gimp_drawable_set_pixel(layer, x, y, 3, (255, 255, 50))

    # zobrazeni
    gimp.Display(image)

    # zajisteni, ze se okno s obrazkem skutecne prekresli
    gimp.displays_flush()



# Registrace skriptu do prosteedi grafickeho editoru GIMP
# a specifikace parametru nastavitelnych uzivatelem,
# ktere se posleze prenesou jako parametry skriptu.
register(
    "create_starry_sky_1",
    "Vytvor novy obrazek s hvezdnou oblohou",
    "Vytvor novy obrazek s hvezdnou oblohou",
    "Pavel Tisnovsky",
    "Open source",
    "2017-03-16",
    "Vytvor novy obrazek s hvezdnou oblohou",
    "", # plugin se spusti jen pokud neexistuje obrazek
    [
        (PF_SPINNER, "width",  "Image width",  256, (16, 8192, 16)),
        (PF_SPINNER, "height", "Image height", 256, (16, 8192, 16)),
        (PF_SPINNER, "stars",  "Stars",        250, (10, 2000, 10))
    ],
    [],
    create_starry_sky_1,
    menu="<Image>/Filters/Test/")

main()

Připomeňme si způsob instalace pluginu naprogramovaného v Pythonu. Celá „instalace“ skládá z pouhých dvou kroků:

  1. Kopie zdrojového kódu pluginu do adresáře ~/.gimp-2.x/plug-ins, kde x je číslo verze GIMPu. Pro jistotu si zkontrolujte, zda se tento adresář skutečně používá.
  2. Nastavení příznaku spouštění (+x). Pokud totiž nebude skript s pluginem spustitelný, bude ho GIMP ignorovat! (dokonce ho ani nezobrazí v seznamu dostupných pluginů). Proto je zapotřebí povolit jeho spuštění aktivním uživatelem, a to konkrétně příkazem chmod u+x cesta/jméno_skriptu.py, například chmod u+x ~/.gimp-2.8/plug-ins/stars1.py (2.8 nahraďte aktuálně používanou verzí).

4. Vykreslení hvězd s využitím aktuálně nastavené tužky

Již minule jsme se zmínili o tom, že kreslení na úrovni jednotlivých pixelů není v žádném případě typickou operací, kterou skripty určené pro grafický editor GIMP provádí (tuto operaci najdeme jen u několika pluginů). Navíc se jedná i o dosti pomalou operaci, protože plugin vlastně musí nepřímo volat nativní funkce GIMPu. Mnohem častěji se tudíž můžeme setkat se skripty, které kreslí či modifikují obrázek s využitím nástrojů dostupných samotným uživatelům GIMPu, což je samozřejmě mnohem zajímavější a užitečnější, neboť tyto nástroje jsou plně konfigurovatelné, a to jak programově (přímo ze spuštěného skriptu), tak i z grafického uživatelského rozhraní GIMPu (dialogy zobrazované pluginem atd.).

Obrázek 4: Výsledek běhu demonstračního příkladu z předchozího článku při malování štětcem (brush).

Proto si předchozí verzi pluginu zkusíme nepatrně upravit, a to konkrétně tak, že namísto kreslení na úrovni jednotlivých pixelů použijeme nástroj tužky (pencil). V praxi to konkrétně bude znamenat náhradu řádku:

(gimp-drawable-set-pixel layer x y 3 pixel))

za řádek:

(gimp-pencil layer 2 point))

Co však znamenají parametry 2 a point? Funkce gimp-pencil vyžaduje zadání hladiny, do které se má vykreslovat, dále pak počtu předaných souřadnic a následně taktéž pole vrcholů tvořících stopu tužky. My potřebujeme vykreslit izolované hvězdy (body), takže počet souřadnic bude roven dvěma (jedná se pouze o souřadnice x a y) a pole vrcholů bude logicky obsahovat právě dvě souřadnice. Pole je v programovacím jazyku Scheme reprezentováno takzvanými vektory, jejichž prvky se nastavují funkcí vector-set!. Této funkci je nutné předat vlastní vektor, index měněného prvku a jeho novou hodnotu. Vykreslení jedné hvězdy na náhodně zvolené souřadnice [x,y] tedy bude implementováno přibližně následujícím způsobem:

(let* ((point (make-vector 2))
       (x (rand width))
       (y (rand width)))
   (vector-set! point 0 x)
   (vector-set! point 1 y)
   ; vykreslení hvězdy aktuálně nastavenou tužkou
   (gimp-pencil layer 2 point))

Poznámka: blok začínající let* nám umožňuje snadno vytvořit lokální proměnné (jinými slovy hodnoty navázané na symboly). Zde se konkrétně jedná o proměnné point, x a y. Tyto proměnné jsou platné pouze v daném bloku, tedy až do poslední pravé uzavírací závorky formy let*.

5. Varianta druhé verze pluginu naprogramovaná ve Scheme

Úprava první verze našeho pluginu takovým způsobem, aby hvězdy vykresloval aktuálně nastaveným nástrojem tužka (pencil) a nikoli přímým vybarvováním jednotlivých pixelů, je jednoduchá, jak je ostatně patrné i z následujícího zdrojového kódu:

; Funkce, která vytvoří nový obrázek o zadané velikosti.
; V obrázku bude jedna hladina nazvaná "Stars" a
; v této hladině bude vykreslena hvězdná obloha.
(define (script-fu-stars-2 width height stars)
    ; definice lokálních proměnných
    (let*
        (
            ; vytvoření nového obrázku, jehož ID se uloží
            ; do proměnné nazvané "image"
            (image (car (gimp-image-new width height RGB)))
            ; vytvoření nové hladiny, jejíž ID se uloží
            ; do proměnné nazvané "layer"
            (layer (car (gimp-layer-new image width height RGB-IMAGE "Stars" 100 NORMAL-MODE))))

        ; zákaz ukládání operací do zásobníku
        (gimp-image-undo-disable image)
        ; přidání hladiny do vytvořeného obrázku
        (gimp-image-add-layer image layer 0)

        ; změna barvy popředí a pozadí
        (gimp-palette-set-foreground '(255 255 0))
        (gimp-context-set-background '(0 0 40))

        ; vyplnění hladiny konstantní barvou
        (gimp-drawable-fill layer 1)  ;0 FG, 1 BG

        (do ((i 0 (+ i 1)))
            ((= i stars))
            (let* ((point (make-vector 2))
                   (x (rand width))
                   (y (rand width)))
               (vector-set! point 0 x)
               (vector-set! point 1 y)
               ; vykreslení hvězdy aktuálně nastavenou tužkou
               (gimp-pencil layer 2 point))
        ) ; end of loop

        ; zobrazení právě vytvořeného obrázku
        (gimp-display-new image)

        ; povolení ukládání operací do zásobníku
        (gimp-image-undo-enable image)))

; Registrace skriptu do prostředí grafického editoru GIMP
; a specifikace proměnných nastavitelných uživatelem,
; které se posléze přenesou jako parametry skriptu.
(script-fu-register "script-fu-stars-2"
                    "<Image>/Filters/Render/Pattern/Stars2"
                    "Vytvori obrazek hvezdnou oblohou."
                    "Pavel Tisnovsky"
                    "Pavel Tisnovsky"
                    "2017-03-16"
                    ""
                    SF-ADJUSTMENT "Image width"  '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Image height" '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Stars"        '(250 10 2000 10 20 0 1)
)

; finito

Obrázek 5: Použití nástroje tužka (pencil), která má stopu nastavenou na 3×3 pixely.

Poznámka: tvar tužky si zvolte ještě před spuštěním pluginu.

6. Varianta druhé verze pluginu naprogramovaná v Pythonu

Ve variantě pluginu určené pro programovací jazyk Python je zapotřebí provést oproti předchozímu příkladu jen jedinou změnu, a to konkrétně náhradu volání pdb.gimp_drawable_set_pixel() za pdb.gimp_pencil():

Funkce ve Scheme Volání v Pythonu
(gimp-pencil) pdb.gimp_pencil()

Upravený zdrojový kód druhé verze pluginu naprogramovaného v Pythonu vypadá takto:

#!/usr/bin/env python

from gimpfu import *
from random import *

# funkce zavolana po spusteni pluginu uzivatelem
def create_starry_sky_2(width, height, stars):
    # vytvoreni noveho obrazku
    image = gimp.Image(int(width), int(height), RGB);

    # vytvoreni nove hladiny
    layer = gimp.Layer(image, "Stars", int(width), int(height), RGB_IMAGE, 100, NORMAL_MODE)

    # nastaveni barvy vykreslovani pozadi (druha barva ve vyberu)
    gimp.set_background(0, 0, 40)

    # nastaveni barvy vykreslovani popredi (prvni barva ve vyberu)
    gimp.set_foreground(255, 255, 0)

    # vyplneni hladiny konstantni barvou
    layer.fill(BACKGROUND_FILL)

    # pridani hladiny do zasobniku hladin v obrazku
    image.add_layer(layer, 0)

    for i in range(int(stars)):
        # pozice hvezdy v obrazku
        x = randint(0, int(width)-1)
        y = randint(0, int(height)-1)
        point = (x, y)
        # vykresleni jedne hvezdy do obrazku
        pdb.gimp_pencil(layer, 2, point)

    # zobrazeni
    gimp.Display(image)

    # zajisteni, ze se okno s obrazkem skutecne prekresli
    gimp.displays_flush()



# Registrace skriptu do prostredi grafickeho editoru GIMP
# a specifikace parametru nastavitelnych uzivatelem,
# ktere se posleze prenesou jako parametry skriptu.
register(
    "create_starry_sky_2",
    "Vytvor novy obrazek s hvezdnou oblohou (2)",
    "Vytvor novy obrazek s hvezdnou oblohou (2)",
    "Pavel Tisnovsky",
    "Open source",
    "2017-03-16",
    "Vytvor novy obrazek s hvezdnou oblohou (2)",
    "", # plugin se spusti jen pokud neexistuje obrazek
    [
        (PF_SPINNER, "width",  "Image width",  256, (16, 8192, 16)),
        (PF_SPINNER, "height", "Image height", 256, (16, 8192, 16)),
        (PF_SPINNER, "stars",  "Stars",        250, (10, 2000, 10))
    ],
    [],
    create_starry_sky_2,
    menu="<Image>/Filters/Test/")

main()

Obrázek 6: Volba příliš velké stopy štětce.

7. Výběr štětce s nastavením velikosti jeho stopy

Předchozí demonstrační příklad sice pracoval korektně, ovšem vyžadoval, aby byla stopa tužky nebo štětce nastavena ještě před vlastním spuštěním skriptu, což je okolnost, kterou uživatelé v naprosté většině případů neočekávají. Proto se pokusíme příklad nepatrně upravit takovým způsobem, aby bylo možné tvar stopy štětce nastavit v konfiguračním dialogu pluginu. Již v předchozí části tohoto seriálu jsme se dozvěděli, že konfigurační dialog skutečně může obsahovat ovládací prvek s výběrem štětce, barvy, barvového přechodu, hladiny atd. Konkrétně v případě výběru štětce se jedná o prvek pojmenovaný SF-BRUSH, který dále může obsahovat návěští (label) a implicitně vybraný štětec. Upravený dialog tedy může vypadat například následovně:

(script-fu-register "script-fu-stars-3"
                    "<Image>/Filters/Render/Pattern/Stars3"
                    "Vytvori obrazek hvezdnou oblohou."
                    "Pavel Tisnovsky"
                    "Pavel Tisnovsky"
                    "2017-03-16"
                    ""
                    SF-ADJUSTMENT "Image width"  '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Image height" '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Stars"        '(250 10 2000 10 20 0 1)
                    SF-BRUSH      "Brush"        '("2. Hardness 075" 100 -1 0)
                    SF-COLOR      "Star colors"  "yellow"
)

Povšimněte si, jakým způsobem se zapisují informace o implicitně vybraném štětci – jedná se o řetězec s velikostí stopy, jménem štětce a stupně barevného krytí.

Obrázek 7: Štětec s „rozmazanou“ stopou.

8. Varianta třetí verze pluginu naprogramovaná ve Scheme

Skript bude samozřejmě zapotřebí nepatrně upravit, a to konkrétně takovým způsobem, že se do jeho funkce bude předávat i informace o vybraném štětci:

(define (script-fu-stars-3 width height stars selected-brush selected-color)

Použití vybraného štětce je snadné (v případě potřeby lze z objektu selected-brush získat i velikost štětce, to se nám zde však moc nehodí):

; nastavení velikosti a tvaru štětce
(gimp-context-set-brush-size 1.0)
(gimp-context-set-brush      (car selected-brush))

Podívejme se na úplný zdrojový kód takto upraveného skriptu:

; Funkce, která vytvoří nový obrázek o zadané velikosti.
; V obrázku bude jedna hladina nazvaná "Stars" a
; v této hladině bude vykreslena hvezdna obloha.
(define (script-fu-stars-3 width height stars selected-brush selected-color)
    ; definice lokálních proměnných
    (let*
        (
            ; vytvoření nového obrázku, jehož ID se uloží
            ; do proměnné nazvané "image"
            (image (car (gimp-image-new width height RGB)))
            ; vytvoření nové hladiny, jejíž ID se uloží
            ; do proměnné nazvané "layer"
            (layer (car (gimp-layer-new image width height RGB-IMAGE "Stars" 100 NORMAL-MODE))))
            ; pole s uloženými RGB hodnotami pixelu

        ; zákaz ukládání operací do zásobníku
        (gimp-image-undo-disable image)
        ; přidání hladiny do vytvořeného obrázku
        (gimp-image-add-layer image layer 0)

        ; změna barvy popředí a pozadí
        (gimp-context-set-background '(0 0 40))
        (gimp-context-set-foreground selected-color)
        ; nastavení velikosti a tvaru štětce
        (gimp-context-set-brush-size 1.0)
        (gimp-context-set-brush      (car selected-brush))

        ; vyplnění hladiny konstantní barvou
        (gimp-drawable-fill layer 1)  ;0 FG, 1 BG

        (do ((i 0 (+ i 1)))
            ((= i stars))
            (let* (
               (point (make-vector 2))
               (x (rand width))
               (y (rand height)))
               (vector-set! point 0 x)
               (vector-set! point 1 y)
               ; vykreslení hvězdy pomocí štětce
               (gimp-paintbrush-default layer 2 point))
        ) ; end of loop

        ; zobrazení právě vytvořeného obrázku
        (gimp-display-new image)

        ; povolení ukládání operací do zásobníku
        (gimp-image-undo-enable image)))

; Registrace skriptu do prostředí grafického editoru GIMP
; a specifikace proměnných nastavitelných uživatelem,
; které se posléze přenesou jako parametry skriptu.
(script-fu-register "script-fu-stars-3"
                    "<Image>/Filters/Render/Pattern/Stars3"
                    "Vytvori obrazek hvezdnou oblohou."
                    "Pavel Tisnovsky"
                    "Pavel Tisnovsky"
                    "2017-03-16"
                    ""
                    SF-ADJUSTMENT "Image width"  '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Image height" '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Stars"        '(250 10 2000 10 20 0 1)
                    SF-BRUSH      "Brush"        '("2. Hardness 075" 100 -1 0)
                    SF-COLOR      "Star colors"  "yellow"
)

; finito

9. Varianta třetí verze pluginu naprogramovaná v Pythonu

Přepis do programovacího jazyka Python vyžaduje v první řadě změnu konfigurace dialogu:

# Registrace skriptu do prostredi grafickeho editoru GIMP
# a specifikace parametru nastavitelnych uzivatelem,
# ktere se posleze prenesou jako parametry skriptu.
register(
    "create_starry_sky_3",
    "Vytvor novy obrazek s hvezdnou oblohou (3)",
    "Vytvor novy obrazek s hvezdnou oblohou (3)",
    "Pavel Tisnovsky",
    "Open source",
    "2017-03-16",
    "Vytvor novy obrazek s hvezdnou oblohou (3)",
    "", # plugin se spusti jen pokud neexistuje obrazek
    [
        (PF_SPINNER, "width",  "Image width",  256, (16, 8192, 16)),
        (PF_SPINNER, "height", "Image height", 256, (16, 8192, 16)),
        (PF_SPINNER, "stars",  "Stars",        250, (10, 2000, 10)),
        (PF_BRUSH,   "brush",  "Brush",        None),
    ],
    [],
    create_starry_sky_3,
    menu="<Image>/Filters/Test/")

Dále pak úpravu hlavičky funkce představující plugin:

# funkce zavolana po spusteni pluginu uzivatelem
def create_starry_sky_3(width, height, stars, brush):

A následně použití objektu představujícího vybraný štětec:

# nastaveni velikosti a tvaru stetce
pdb.gimp_context_set_brush_size(1.0)
pdb.gimp_context_set_brush(brush)

Podívejme se nyní na úplný zdrojový kód takto upraveného skriptu:

#!/usr/bin/env python

from gimpfu import *
from random import *

# funkce zavolana po spusteni pluginu uzivatelem
def create_starry_sky_3(width, height, stars, brush):
    # vytvoreni noveho obrazku
    image = gimp.Image(int(width), int(height), RGB);

    # vytvoreni nove hladiny
    layer = gimp.Layer(image, "Stars", int(width), int(height), RGB_IMAGE, 100, NORMAL_MODE)

    # nastaveni barvy vykreslovani pozadi (druha barva ve vyberu)
    gimp.set_background(0, 0, 40)

    # nastaveni barvy vykreslovani popredi (prvni barva ve vyberu)
    gimp.set_foreground(255, 255, 0)

    # nastaveni velikosti a tvaru stetce
    pdb.gimp_context_set_brush_size(1.0)
    pdb.gimp_context_set_brush(brush)

    # vyplneni hladiny konstantni barvou
    layer.fill(BACKGROUND_FILL)

    # pridani hladiny do zasobniku hladin v obrazku
    image.add_layer(layer, 0)

    for i in range(int(stars)):
        # pozice hvezdy v obrazku
        x = randint(0, int(width)-1)
        y = randint(0, int(height)-1)
        point = (x, y)
        # vykresleni jedne hvezdy do obrazku
        pdb.gimp_paintbrush_default(layer, 2, point)

    # zobrazeni
    gimp.Display(image)

    # zajisteni, ze se okno s obrazkem skutecne prekresli
    gimp.displays_flush()



# Registrace skriptu do prostredi grafickeho editoru GIMP
# a specifikace parametru nastavitelnych uzivatelem,
# ktere se posleze prenesou jako parametry skriptu.
register(
    "create_starry_sky_3",
    "Vytvor novy obrazek s hvezdnou oblohou (3)",
    "Vytvor novy obrazek s hvezdnou oblohou (3)",
    "Pavel Tisnovsky",
    "Open source",
    "2017-03-16",
    "Vytvor novy obrazek s hvezdnou oblohou (3)",
    "", # plugin se spusti jen pokud neexistuje obrazek
    [
        (PF_SPINNER, "width",  "Image width",  256, (16, 8192, 16)),
        (PF_SPINNER, "height", "Image height", 256, (16, 8192, 16)),
        (PF_SPINNER, "stars",  "Stars",        250, (10, 2000, 10)),
        (PF_BRUSH,   "brush",  "Brush",        None),
    ],
    [],
    create_starry_sky_3,
    menu="<Image>/Filters/Test/")

main()

10. Proměnná a konfigurovatelná velikost hvězd

Obrázky vytvořené předchozími variantami pluginu ve skutečnosti nevypadají příliš přirozeně, protože všechny hvězdy mají stejnou velikost (která odpovídá svítivosti). I tento nedostatek můžeme napravit. Nejprve se vrátíme zpět k vykreslování jednotlivých pixelů, ovšem náš plugin upravíme takovým způsobem, že bude vykreslovat tři velikosti hvězd. Nejmenší hvězdy budou mít velikost jeden pixel, prostřední hvězdy velikost 2×2 pixely a hvězdy největší budou mít velikost 3×3 pixely. K tomu nám pomohou pomocné funkce:

(define (pixel-1x1 layer x y pixel)
    (gimp-drawable-set-pixel layer x y 3 pixel))

(define (pixel-2x2 layer x y pixel)
    (gimp-drawable-set-pixel layer x       y       3 pixel)
    (gimp-drawable-set-pixel layer (+ 1 x) y       3 pixel)
    (gimp-drawable-set-pixel layer x       (+ 1 y) 3 pixel)
    (gimp-drawable-set-pixel layer (+ 1 x) (+ 1 y) 3 pixel))

(define (pixel-3x3 layer x y pixel)
    (gimp-drawable-set-pixel layer x       y       3 pixel)
    (gimp-drawable-set-pixel layer (+ 1 x) y       3 pixel)
    (gimp-drawable-set-pixel layer (+ 2 x) y       3 pixel)
    (gimp-drawable-set-pixel layer x       (+ y 1) 3 pixel)
    (gimp-drawable-set-pixel layer (+ 1 x) (+ y 1) 3 pixel)
    (gimp-drawable-set-pixel layer (+ 2 x) (+ y 1) 3 pixel)
    (gimp-drawable-set-pixel layer x       (+ y 2) 3 pixel)
    (gimp-drawable-set-pixel layer (+ 1 x) (+ y 2) 3 pixel)
    (gimp-drawable-set-pixel layer (+ 2 x) (+ y 2) 3 pixel))

Dále upravíme skript takovým způsobem, že se vykreslí určitý počet malých hvězd, určitý počet hvězd větších a následně hvězdy největší:

(do ((i 0 (+ i 1)))
    ((= i stars1))
    (let* (
       (x (rand width))
       (y (rand height)))
       ; vykreslení hvězdy
       (pixel-1x1 layer x y pixel)))

(do ((i 0 (+ i 1)))
    ((= i stars2))
    (let* (
       (x (rand (- width 1)))
       (y (rand (- height 1))))
       ; vykreslení hvězdy
       (pixel-2x2 layer x y pixel)))

(do ((i 0 (+ i 1)))
    ((= i stars3))
    (let* (
       (x (rand (- width 2)))
       (y (rand (- height 2))))
       ; vykreslení hvězdy
       (pixel-3x3 layer x y pixel)))

Poznámka: samozřejmě je možné namísto tří smyček použít smyčku jedinou, které se předá funkce použitá pro vykreslení. Nicméně předchozí varianta je sice delší, ovšem čitelnější.

Obrázek 8: Obloha vykreslená skriptem používajícím proměnnou velikost hvězd.

Obrázek 9: Pro porovnání: konstantní velikost hvězd.

11. Varianta čtvrté verze pluginu naprogramovaná ve Scheme

Plugin samozřejmě potřebuje úpravu dialogu, v němž si uživatel bude moci vybrat, kolik velkých/malých/středních hvězd si přeje zobrazit:

; Registrace skriptu do prostředí grafického editoru GIMP
; a specifikace proměnných nastavitelných uživatelem,
; které se posléze přenesou jako parametry skriptu.
(script-fu-register "script-fu-stars-4"
                    "<Image>/Filters/Render/Pattern/Stars4"
                    "Vytvori obrazek s hvezdnou oblohou."
                    "Pavel Tisnovsky"
                    "Pavel Tisnovsky"
                    "2017-03-16"
                    ""
                    SF-ADJUSTMENT "Image width"  '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Image height" '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Stars1"       '(200 10 1000 10 20 0 1)
                    SF-ADJUSTMENT "Stars2"       '(50  10 1000 10 20 0 1)
                    SF-ADJUSTMENT "Stars3"       '(5   10 1000 10 20 0 1)
)

Úplný zdrojový kód pluginu vypadá následovně:

; Funkce, která vytvoří nový obrázek o zadané velikosti.
; V obrázku bude jedna hladina nazvaná "Stars" a
; v této hladině bude vykreslena hvezdna obloha.
(define (script-fu-stars-4 width height stars1 stars2 stars3)
    ; definice lokálních proměnných
    (let*
        (
            ; vytvoření nového obrázku, jehož ID se uloží
            ; do proměnné nazvané "image"
            (image (car (gimp-image-new width height RGB)))
            ; vytvoření nové hladiny, jejíž ID se uloží
            ; do proměnné nazvané "layer"
            (layer (car (gimp-layer-new image width height RGB-IMAGE "Stars" 100 NORMAL-MODE)))
            ; pole s uloženými RGB hodnotami pixelu
            (pixel (cons-array 3 'byte)))

        ; barva vykreslovanych hvezd
        (aset pixel 0 255)
        (aset pixel 1 255)
        (aset pixel 2 50)

        ; zákaz ukládání operací do zásobníku
        (gimp-image-undo-disable image)
        ; přidání hladiny do vytvořeného obrázku
        (gimp-image-add-layer image layer 0)

        ; změna barvy popředí a pozadí
        (gimp-palette-set-foreground '(255 255 255))
        (gimp-context-set-background '(0 0 40))

        ; vyplnění hladiny konstantní barvou
        (gimp-drawable-fill layer 1)  ;0 FG, 1 BG

        (define (pixel-1x1 layer x y pixel)
            (gimp-drawable-set-pixel layer x y 3 pixel))

        (define (pixel-2x2 layer x y pixel)
            (gimp-drawable-set-pixel layer x       y       3 pixel)
            (gimp-drawable-set-pixel layer (+ 1 x) y       3 pixel)
            (gimp-drawable-set-pixel layer x       (+ 1 y) 3 pixel)
            (gimp-drawable-set-pixel layer (+ 1 x) (+ 1 y) 3 pixel))

        (define (pixel-3x3 layer x y pixel)
            (gimp-drawable-set-pixel layer x       y       3 pixel)
            (gimp-drawable-set-pixel layer (+ 1 x) y       3 pixel)
            (gimp-drawable-set-pixel layer (+ 2 x) y       3 pixel)
            (gimp-drawable-set-pixel layer x       (+ y 1) 3 pixel)
            (gimp-drawable-set-pixel layer (+ 1 x) (+ y 1) 3 pixel)
            (gimp-drawable-set-pixel layer (+ 2 x) (+ y 1) 3 pixel)
            (gimp-drawable-set-pixel layer x       (+ y 2) 3 pixel)
            (gimp-drawable-set-pixel layer (+ 1 x) (+ y 2) 3 pixel)
            (gimp-drawable-set-pixel layer (+ 2 x) (+ y 2) 3 pixel))

        (do ((i 0 (+ i 1)))
            ((= i stars1))
            (let* (
               (x (rand width))
               (y (rand height)))
               ; vykreslení hvězdy
               (pixel-1x1 layer x y pixel))
        ) ; end of loop

        (do ((i 0 (+ i 1)))
            ((= i stars2))
            (let* (
               (x (rand (- width 1)))
               (y (rand (- height 1))))
               ; vykreslení hvězdy
               (pixel-2x2 layer x y pixel))
        ) ; end of loop

        (do ((i 0 (+ i 1)))
            ((= i stars3))
            (let* (
               (x (rand (- width 2)))
               (y (rand (- height 2))))
               ; vykreslení hvězdy
               (pixel-3x3 layer x y pixel))
        ) ; end of loop

        ; zobrazení právě vytvořeného obrázku
        (gimp-display-new image)

        ; povolení ukládání operací do zásobníku
        (gimp-image-undo-enable image)))

; Registrace skriptu do prostředí grafického editoru GIMP
; a specifikace proměnných nastavitelných uživatelem,
; které se posléze přenesou jako parametry skriptu.
(script-fu-register "script-fu-stars-4"
                    "<Image>/Filters/Render/Pattern/Stars4"
                    "Vytvori obrazek s hvezdnou oblohou."
                    "Pavel Tisnovsky"
                    "Pavel Tisnovsky"
                    "2017-03-16"
                    ""
                    SF-ADJUSTMENT "Image width"  '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Image height" '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Stars1"       '(200 10 1000 10 20 0 1)
                    SF-ADJUSTMENT "Stars2"       '(50  10 1000 10 20 0 1)
                    SF-ADJUSTMENT "Stars3"       '(5   10 1000 10 20 0 1)
)

; finito

Obrázek 10: Zvětšená část obrázku, na níž jsou vidět skutečné tvary hvězd.

12. Varianta čtvrté verze pluginu naprogramovaná v Pythonu

Přepis čtvrté verze pluginu do programovacího jazyka Python je přímočará, protože i zde si vytvoříme pomocné funkce pixel_1x1, pixel_2x2 a pixel_3x3, které postupně zavoláme ve třech programových smyčkách:

for i in range(int(stars1)):
    # pozice hvezdy v obrazku
    x = randint(0, int(width)-1)
    y = randint(0, int(height)-1)
    # vykresleni jedne hvezdy do obrazku
    pixel_1x1(layer, x, y, star_color)

for i in range(int(stars2)):
    # pozice hvezdy v obrazku
    x = randint(0, int(width)-2)
    y = randint(0, int(height)-2)
    # vykresleni jedne hvezdy do obrazku
    pixel_2x2(layer, x, y, star_color)

for i in range(int(stars3)):
    # pozice hvezdy v obrazku
    x = randint(0, int(width)-3)
    y = randint(0, int(height)-3)
    # vykresleni jedne hvezdy do obrazku
    pixel_3x3(layer, x, y, star_color)

Úplný zdrojový kód čtvrté varianty pluginu vypadá následovně:

#!/usr/bin/env python

from gimpfu import *
from random import *

def pixel_1x1(drawable, x, y, color):
    pdb.gimp_drawable_set_pixel(drawable, x, y, 3, color)

def pixel_2x2(drawable, x, y, color):
    pdb.gimp_drawable_set_pixel(drawable, x, y, 3, color)
    pdb.gimp_drawable_set_pixel(drawable, x+1, y, 3, color)
    pdb.gimp_drawable_set_pixel(drawable, x, y+1, 3, color)
    pdb.gimp_drawable_set_pixel(drawable, x+1, y+1, 3, color)

def pixel_3x3(drawable, x, y, color):
    for dy in range(0, 3):
        for dx in range(0, 3):
            pdb.gimp_drawable_set_pixel(drawable, x+dx, y+dy, 3, color)

# funkce zavolana po spusteni pluginu uzivatelem
def create_starry_sky_4(width, height, stars1, stars2, stars3):
    # vytvoreni noveho obrazku
    image = gimp.Image(int(width), int(height), RGB);

    # vytvoreni nove hladiny
    layer = gimp.Layer(image, "Stars", int(width), int(height), RGB_IMAGE, 100, NORMAL_MODE)

    # nastaveni barvy vykreslovani pozadi (druha barva ve vyberu)
    gimp.set_background(0, 0, 40)

    # vyplneni hladiny konstantni barvou
    layer.fill(BACKGROUND_FILL)

    # pridani hladiny do zasobniku hladin v obrazku
    image.add_layer(layer, 0)

    star_color = (255, 255, 50)

    for i in range(int(stars1)):
        # pozice hvezdy v obrazku
        x = randint(0, int(width)-1)
        y = randint(0, int(height)-1)
        # vykresleni jedne hvezdy do obrazku
        pixel_1x1(layer, x, y, star_color)

    for i in range(int(stars2)):
        # pozice hvezdy v obrazku
        x = randint(0, int(width)-2)
        y = randint(0, int(height)-2)
        # vykresleni jedne hvezdy do obrazku
        pixel_2x2(layer, x, y, star_color)

    for i in range(int(stars3)):
        # pozice hvezdy v obrazku
        x = randint(0, int(width)-3)
        y = randint(0, int(height)-3)
        # vykresleni jedne hvezdy do obrazku
        pixel_3x3(layer, x, y, star_color)

    # zobrazeni
    gimp.Display(image)

    # zajisteni, ze se okno s obrazkem skutecne prekresli
    gimp.displays_flush()



# Registrace skriptu do prostredi grafickeho editoru GIMP
# a specifikace parametru nastavitelnych uzivatelem,
# ktere se posleze prenesou jako parametry skriptu.
register(
    "create_starry_sky_4",
    "Vytvor novy obrazek s hvezdnou oblohou (4)",
    "Vytvor novy obrazek s hvezdnou oblohou (4)",
    "Pavel Tisnovsky",
    "Open source",
    "2017-03-16",
    "Vytvor novy obrazek s hvezdnou oblohou (4)",
    "", # plugin se spusti jen pokud neexistuje obrazek
    [
        (PF_SPINNER, "width",  "Image width",  256, (16, 8192, 16)),
        (PF_SPINNER, "height", "Image height", 256, (16, 8192, 16)),
        (PF_SPINNER, "stars1", "Stars1",       200, (10, 2000, 10)),
        (PF_SPINNER, "stars2", "Stars2",       50,  (10, 2000, 10)),
        (PF_SPINNER, "stars3", "Stars3",       5,   (10, 2000, 10))
    ],
    [],
    create_starry_sky_4,
    menu="<Image>/Filters/Test/")

main()

Obrázek 11: Dialog čtvrté a páté varianty pluginu s výběrem počtu malých/velkých/středních hvězd.

13. Přidání druhé vrstvy s rozmazanými hvězdami

Hvězdnou oblohu je možné vylepšit, a to mnoha různými způsoby. Jeden z nejjednodušších způsobů spočívá v přidání další vrstvy, v níž budou hvězdy rozmazány, konkrétně Gaussovým filtrem s následnou normalizací. Výsledek vypadá zhruba takto:

Obrázek 12: Vrstva s rozmazanými hvězdami.

Ovšem vzhledem k tomu, že se rozmazáním ztratí přesná kontura hvězd, vyzkoušíme malý trik – původní vrstvu zkombinujeme s vrstvou novou použitím režimu nazvaného Screen mode (https://docs.gimp.org/en/gimp-concepts-layer-modes.html). Při použití tohoto režimu se nejprve pixely z obou vrstev invertují, následně se vynásobí, vydělí konstantou 255 a znovu se invertují. Výsledkem je obrázek, v němž přes rozmazané skvrny hvězd můžeme vidět i původní nerozmazané kontury:

Obrázek 13: Původní vrstva překrytá s vrstvou s rozmazanými hvězdami. Při kombinaci vrstev se používá Screen mode.

Při tvorbě obrázku s rozmazanými hvězdami budeme postupovat následujícím způsobem. Nejprve vytvoříme novou vrstvu, která bude kopií vrstvy původní:

; vytvoreni nove vrstvy kopii stavajici vrstvy
(define blurred-stars
    (car (gimp-layer-copy layer 1)))

Následně se vrstva přidá do zásobníku vrstev a nastaví se jako vrstva aktivní:

(gimp-image-add-layer image blurred-stars -1)
(gimp-image-set-active-layer image blurred-stars)

Nyní již můžeme aplikovat vybrané filtry, konkrétně Gaussovo rozmazání a normalizaci:

; aplikace dvojice filtru
(plug-in-gauss-rle 1 image blurred-stars 5 1 1)
(plug-in-normalize 1 image blurred-stars)

Nastavíme základní parametry vrstvy a její jméno. Povšimněte se především nastavení režimu zobrazení a kombinace vrstev (SCREEN-MODE):

; nastaveni parametru vrstvy
(gimp-layer-set-mode blurred-stars SCREEN-MODE)
(gimp-layer-set-name blurred-stars "blurred-stars")

Nakonec se výsledná bitmapa zobrazí:

; zobrazení právě vytvořeného obrázku
(gimp-display-new image)

Obrázek 14: Zvýšení celkového počtu hvězd.

14. Varianta páté verze pluginu naprogramovaná ve Scheme

Úplný zdrojový kód příkladu, v němž se navíc vytvoří nová vrstva s rozmazaným obrázkem, vypadá následovně. Prozatím si uvedeme jen variantu vytvořenou v programovacím jazyku Scheme:

; Funkce, která vytvoří nový obrázek o zadané velikosti.
; V obrázku bude jedna hladina nazvaná "Stars" a
; v této hladině bude vykreslena hvezdna obloha.
(define (script-fu-stars-5 width height stars1 stars2 stars3)
    ; definice lokálních proměnných
    (let*
        (
            ; vytvoření nového obrázku, jehož ID se uloží
            ; do proměnné nazvané "image"
            (image (car (gimp-image-new width height RGB)))
            ; vytvoření nové hladiny, jejíž ID se uloží
            ; do proměnné nazvané "layer"
            (layer (car (gimp-layer-new image width height RGB-IMAGE "Stars" 100 NORMAL-MODE)))
            ; pole s uloženými RGB hodnotami pixelu
            (pixel (cons-array 3 'byte)))

        ; barva vykreslovanych hvezd
        (aset pixel 0 255)
        (aset pixel 1 255)
        (aset pixel 2 50)

        ; zákaz ukládání operací do zásobníku
        (gimp-image-undo-disable image)
        ; přidání hladiny do vytvořeného obrázku
        (gimp-image-add-layer image layer 0)

        ; změna barvy popředí a pozadí
        (gimp-palette-set-foreground '(255 255 255))
        (gimp-context-set-background '(0 0 40))

        ; vyplnění hladiny konstantní barvou
        (gimp-drawable-fill layer 1)  ;0 FG, 1 BG

        (define (pixel-1x1 layer x y pixel)
            (gimp-drawable-set-pixel layer x y 3 pixel))

        (define (pixel-2x2 layer x y pixel)
            (gimp-drawable-set-pixel layer x       y       3 pixel)
            (gimp-drawable-set-pixel layer (+ 1 x) y       3 pixel)
            (gimp-drawable-set-pixel layer x       (+ 1 y) 3 pixel)
            (gimp-drawable-set-pixel layer (+ 1 x) (+ 1 y) 3 pixel))

        (define (pixel-3x3 layer x y pixel)
            (gimp-drawable-set-pixel layer x       y       3 pixel)
            (gimp-drawable-set-pixel layer (+ 1 x) y       3 pixel)
            (gimp-drawable-set-pixel layer (+ 2 x) y       3 pixel)
            (gimp-drawable-set-pixel layer x       (+ y 1) 3 pixel)
            (gimp-drawable-set-pixel layer (+ 1 x) (+ y 1) 3 pixel)
            (gimp-drawable-set-pixel layer (+ 2 x) (+ y 1) 3 pixel)
            (gimp-drawable-set-pixel layer x       (+ y 2) 3 pixel)
            (gimp-drawable-set-pixel layer (+ 1 x) (+ y 2) 3 pixel)
            (gimp-drawable-set-pixel layer (+ 2 x) (+ y 2) 3 pixel))

        (do ((i 0 (+ i 1)))
            ((= i stars1))
            (let* (
               (x (rand width))
               (y (rand height)))
               ; vykreslení hvězdy
               (pixel-1x1 layer x y pixel))
        ) ; end of loop

        (do ((i 0 (+ i 1)))
            ((= i stars2))
            (let* (
               (x (rand (- width 1)))
               (y (rand (- height 1))))
               ; vykreslení hvězdy
               (pixel-2x2 layer x y pixel))
        ) ; end of loop

        (do ((i 0 (+ i 1)))
            ((= i stars3))
            (let* (
               (x (rand (- width 2)))
               (y (rand (- height 2))))
               ; vykreslení hvězdy
               (pixel-3x3 layer x y pixel))
        ) ; end of loop

        ; vytvoreni nove vrstvy kopii stavajici vrstvy
        (define blurred-stars
            (car (gimp-layer-copy layer 1)))

        (gimp-image-add-layer image blurred-stars -1)
        (gimp-image-set-active-layer image blurred-stars)

        ; aplikace dvojice filtru
        (plug-in-gauss-rle 1 image blurred-stars 5 1 1)
        (plug-in-normalize 1 image blurred-stars)

        ; nastaveni parametru vrstvy
        (gimp-layer-set-mode blurred-stars SCREEN-MODE)
        (gimp-layer-set-name blurred-stars "blurred-stars")

        ; zobrazení právě vytvořeného obrázku
        (gimp-display-new image)

        ; povolení ukládání operací do zásobníku
        (gimp-image-undo-enable image)))

; Registrace skriptu do prostředí grafického editoru GIMP
; a specifikace proměnných nastavitelných uživatelem,
; které se posléze přenesou jako parametry skriptu.
(script-fu-register "script-fu-stars-5"
                    "<Image>/Filters/Render/Pattern/Stars5"
                    "Vytvori obrazek s hvezdnou oblohou."
                    "Pavel Tisnovsky"
                    "Pavel Tisnovsky"
                    "2017-03-16"
                    ""
                    SF-ADJUSTMENT "Image width"  '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Image height" '(256 16 8192 16 64 0 1)
                    SF-ADJUSTMENT "Stars1"       '(200 10 1000 10 20 0 1)
                    SF-ADJUSTMENT "Stars2"       '(50  10 1000 10 20 0 1)
                    SF-ADJUSTMENT "Stars3"       '(5   10 1000 10 20 0 1)
)

; finito

15. Repositář s demonstračními příklady

Všechny dnes popisované demonstrační příklady byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/presentations. Příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý repositář:

Příklad Odkaz
stars1.scm https://github.com/tisnik/presentations/blob/master/gimp/scheme/stars1.scm
stars1.py https://github.com/tisnik/presentations/blob/master/gimp/GIMP-Python/stars1.py
stars2.scm https://github.com/tisnik/presentations/blob/master/gimp/scheme/stars2.scm
stars2.py https://github.com/tisnik/presentations/blob/master/gimp/GIMP-Python/stars2.py
stars3.scm https://github.com/tisnik/presentations/blob/master/gimp/scheme/stars3.scm
stars3.py https://github.com/tisnik/presentations/blob/master/gimp/GIMP-Python/stars3.py
stars4.scm https://github.com/tisnik/presentations/blob/master/gimp/scheme/stars4.scm
stars4.py https://github.com/tisnik/presentations/blob/master/gimp/GIMP-Python/stars4.py
stars5.scm https://github.com/tisnik/presentations/blob/master/gimp/scheme/stars5.scm

16. Odkazy na Internetu

  1. GIMP Home Page
    http://www.gimp.org/
  2. GIMP Python Documentation
    https://www.gimp.org/docs/python/
  3. Writing GIMP Scripts and Plug-Ins
    http://gimpbook.com/scripting/
  4. GIMP Scripts and Plug-ins (slajdy)
    http://gimpbook.com/scripting/slides/index.html
  5. Use Python to write plug-ins for GIMP
    http://www.ibm.com/developerworks/library/os-autogimp/index.html
  6. A Script-Fu Tutorial
    http://www.linuxtopia.org/online_books/graphics_tools/gimp_user_manual/en/gimp-using-script-fu-tutorial.html
  7. A Script-Fu Tutorial
    http://docs.gimp.org/en/gimp-using-script-fu-tutorial.html
  8. Scheme control structures
    http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-6.html#node_chap_5
  9. GIMP Python Documentation
    https://www.gimp.org/docs/python/pygimp.html
  10. Digital Watercolor with Mypaint 0.9 and Gimp-painter (video)
    https://vimeo.com/18157214
  11. Water in Nature – a MyPaint + GIMP tutorial
    http://www.gimptalk.com/index.php?showtopic=37706
  12. MyPaint (Wikipedia)
    https://en.wikipedia.org/wiki/MyPaint
  13. David Revoy (mj. používá MyPaint, GIMP i Kritu)
    http://davidrevoy.com/
  14. Tux Paint Home Page
    http://www.tuxpaint.org/
  15. Tux Paint (Wikipedia)
    https://en.wikipedia.org/wiki/Tux_Paint
  16. MyPaint Home Page
    http://mypaint.org/
  17. MyPaint – Documentation
    https://github.com/mypaint/mypaint/wiki/Documentation
  18. Gamut
    https://cs.wikipedia.org/wiki/Gamut
  19. MtPaint Home Page
    http://mtpaint.sourceforge.net/
  20. The mtPaint Handbook
    http://mtpaint.sourceforge.net/handbook/en_GB/chap_00.html
  21. MtPaint na Free Software Directory
    https://directory.fsf.org/wiki/MtPaint
  22. XPaint (minimalisticky pojatá home page)
    http://sf-xpaint.sourceforge.net/
  23. XPaint (Wikipedia)
    https://en.wikipedia.org/wiki/XPaint
  24. X Athena Widgets
    https://en.wikipedia.org/wiki/X_Athena_Widgets
  25. Pinta: Painting Made Simple
    https://pinta-project.com/pintaproject/pinta/
  26. Pinta (software)
    https://en.wikipedia.org/wiki/Pinta_%28software%29
  27. Krita Home Page
    https://krita.org/en/
  28. Krita (Wikipedia)
    https://en.wikipedia.org/wiki/Krita
  29. Pinta – Image Editing Alternative to The GIMP
    https://www.maketecheasier.com/pinta-image-editing-alternative-to-the-gimp/
  30. GNU Paint Homepage
    https://www.gnu.org/software/gpaint/
  31. GNU Paint na FreeCode
    http://freecode.com/projects/gpaint/
  32. KolourPaint – Paint Program
    https://www.kde.org/applications/graphics/kolourpaint/
  33. The KolourPaint Handbook
    https://docs.kde.org/stable5/en/kdegraphics/kolourpaint/index.html
  34. KolourPaint (Wikipedia)
    https://en.wikipedia.org/wiki/KolourPaint
  35. KIconEdit – Icon Editor
    https://www.kde.org/applications/graphics/kiconedit/
  36. Phatch (Wikipedia)
    https://en.wikipedia.org/wiki/Phatch
  37. GrafX2 Home Page
    http://pulkomandy.tk/projects/GrafX2
  38. GrafX2 (Wikipedia)
    https://en.wikipedia.org/wiki/GrafX2
  39. Resurgence of Pixel art
    http://www.developmentguruji.com/blog/142/Resurgence-of-Pixel-Art.html
  40. Citypixel
    http://www.citypixel.com/index.htm