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

GEGL operations exposed to Python-Fu - WIP 72 ops wrapped

Sun Nov 05, 2023 9:40 pm

1. Since paynekj allowed dinasset to call GEGL functions with the zip found here: viewtopic.php?f=9&t=18040&p=254914#p255005
2. I thought I would try and parse all functions descriptions found on https://www.gegl.org/operations
3. Turn them into (wrapper) Python-Fu functions which will use the commented out python_fu_dinasset_gegl_graph (found in point 1)

It's an idea, not sure if I can do it I am only 65% sure, but this post is here to show progress.

EDIT ------
72 out of 256 code sections generated (0.28%) have been exposed.
Jump to get py files to work with these 72

Re: GEGL operations exposed to Python-Fu - WIP

Sun Nov 05, 2023 9:53 pm

What I am unsure about is the the pads.
Sometimes it's input output for example gegl:c2g
but it's more like for gegl:displace
pads: aux2 aux input output
I have no clue how to deal with that.

Re: GEGL operations exposed to Python-Fu - WIP

Sun Nov 05, 2023 10:17 pm

ok so I parsed and think I have these info which will be needed to construct the automated Python-Fu generation.
sample of a few of them at the start. (The result1.txt attached has all of them)
Code:
=====
MAIN_NAME:gegl:absolute
PADS:pads: input output
=====
MAIN_NAME:gegl:add
PADS:pads: aux input output
name: value type: double default: 0.00 minimum: -inf maximum: +inf ui-minimum: -1.00 ui-maximum: 1.00 ui-gamma: 1.00 ui-step-small: 0.00 ui-step-big: 0.10 ui-digits: 3
=====
MAIN_NAME:gegl:alien-map
PADS:pads: input output
name: color-model type: enum
name: cpn-1-frequency type: double default: 1.00 minimum: 0.00 maximum: 20.00 ui-minimum: 0.00 ui-maximum: 20.00 ui-gamma: 1.00 ui-step-small: 0.01 ui-step-big: 1.00 ui-digits: 3 label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] sensitive:! cpn-1-keep rgb-label:Red frequency hsl-label:Hue frequency
name: cpn-2-frequency type: double default: 1.00 minimum: 0.00 maximum: 20.00 ui-minimum: 0.00 ui-maximum: 20.00 ui-gamma: 1.00 ui-step-small: 0.01 ui-step-big: 1.00 ui-digits: 3 label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] sensitive:! cpn-2-keep rgb-label:Green frequency hsl-label:Saturation frequency
name: cpn-3-frequency type: double default: 1.00 minimum: 0.00 maximum: 20.00 ui-minimum: 0.00 ui-maximum: 20.00 ui-gamma: 1.00 ui-step-small: 0.01 ui-step-big: 1.00 ui-digits: 3 label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] sensitive:! cpn-3-keep rgb-label:Blue frequency hsl-label:Lightness frequency
name: cpn-1-phaseshift type: double default: 0.00 minimum: 0.00 maximum: 360.00 ui-minimum: 0.00 ui-maximum: 360.00 ui-gamma: 1.00 ui-step-small: 1.00 ui-step-big: 15.00 ui-digits: 2 label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] sensitive:! cpn-1-keep unit:degree rgb-label:Red phase shift hsl-label:Hue phase shift
name: cpn-2-phaseshift type: double default: 0.00 minimum: 0.00 maximum: 360.00 ui-minimum: 0.00 ui-maximum: 360.00 ui-gamma: 1.00 ui-step-small: 1.00 ui-step-big: 15.00 ui-digits: 2 label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] sensitive:! cpn-2-keep unit:degree rgb-label:Green phase shift hsl-label:Saturation phase shift
name: cpn-3-phaseshift type: double default: 0.00 minimum: 0.00 maximum: 360.00 ui-minimum: 0.00 ui-maximum: 360.00 ui-gamma: 1.00 ui-step-small: 1.00 ui-step-big: 15.00 ui-digits: 2 label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] sensitive:! cpn-3-keep unit:degree rgb-label:Blue phase shift hsl-label:Lightness phase shift
name: cpn-1-keep type: boolean default: False label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] rgb-label:Keep red component hsl-label:Keep hue component
name: cpn-2-keep type: boolean default: False label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] rgb-label:Keep green component hsl-label:Keep saturation component
name: cpn-3-keep type: boolean default: False label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] rgb-label:Keep blue component hsl-label:Keep lightness component


post #6 has code that turns the attached below file into python fu procedures that can call gegl ops

Re: GEGL operations exposed to Python-Fu - WIP

Sun Nov 05, 2023 10:30 pm

does anyone know if

name: cpn-3-keep type: boolean default: False label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] rgb-label:Keep blue component hsl-label:Keep lightness component

is equivalent to
(PF_OPTION,"cpn-3-keep", "OPTION:", 0, ["Keep blue component","Keep lightness component"]),

Am I even close? boolean? and then a bunch of labels?
or do I have to map rgb and hsl to some other constant numbers?

Re: GEGL operations exposed to Python-Fu - WIP

Mon Nov 06, 2023 7:08 am

oh here's the code i used to get above result1.txt which downloads from gegl operations and do some simple parsing and formating
just a standalone python script (not plug-in).
Code:
import requests
import re
def strip_html_tags(html_string):
   
    # Remove newlines
    html_string = html_string.replace('\n', ' ') #remove all new lines

    # Replace <br> or <br/> with a newline
    html_string = re.sub(r'<br\s*\/?>', '\n', html_string) #newline

    # Replace </div> with a newline
    html_string = re.sub(r'</div>', '\n', html_string) #newline

    html_string = html_string.replace("&nbsp;", " ") #put in spaces
    html_string = html_string.replace("&nbsp", " ") #put in spaces
    html_string = html_string.replace("  ", " ") #put in spaces


    # Define a regular expression to match HTML tags
    html_tag_pattern = re.compile(r'<[^>]+>')

    # Use the sub() method to replace all HTML tags with an empty string
    plain_text = re.sub(html_tag_pattern, '', html_string)

    return plain_text
def download_and_get_html(link):
    response = requests.get(link)
    if response.status_code == 200:
        return response.text
    else:
        print(f"Failed to download {link}. Status code: {response.status_code}")
        return None

# URL of the web page to download
url = "https://www.gegl.org/operations/"

# Send an HTTP GET request to the URL
response = requests.get(url)

# Check if the request was successful (status code 200)
if response.status_code == 200:
    # Extract links that start with "gegl-" or "svg-" and end with ".html" using regular expressions
    links = re.findall(r'href=["\'](gegl-[^\s"\']*\.html|svg-[^\s"\']*\.html)', response.text)

    # Download and display the HTML content of each link
    for link in links:
        html_text = download_and_get_html(url+link)
        if html_text is not None:
            # Display the HTML text for each link
            html_text = strip_html_tags(html_text)
            lines = html_text.split("\n")
            #GET MAIN NAME:
            NAME_DEFINED = 0
            main_name = ""
            varlines = []
            pads = ""
            for i in range(len(lines)-1,-1,-1):
                line = lines[i].strip()
                elements = line.split(" ")
                if elements[0] == "name:":
                    if NAME_DEFINED == 0: #IT's FUNCTION NAME
                        NAME_DEFINED = 1
                        main_name = elements[1]
                    else:        #IT'S SOME VARIABLE NAME but in reverse order since we're reading backward
                        varlines.append(line) #add to parse later after we reverse it
                if elements[0] == "pads:":
                    pads=line;
            varlines.reverse()
            print("=====")
            print("MAIN_NAME:" + main_name)
            print("PADS:" + pads)
            for j in range(0,len(varlines)):
                print(varlines[j])

else:
    print("Failed to retrieve the web page. Status code:", response.status_code)

Re: GEGL operations exposed to Python-Fu - WIP

Mon Nov 06, 2023 11:09 am

I think I made pretty good progress (other than funky ones that has "pads" which are more than 2)

The below code generates code from result1.txt (mentioned in post post #3)
Code:
typelines = set()
def extract_distinct_types(content):
    types = set()
   
    # Split the content into lines
    lines = content.split('\n')
   
    for line in lines:
        # Find " type: " in the line
        index = line.find(" type: ")
        if index != -1:
            # Extract the type following " type: "
            type_start = index + len(" type: ")
            type_end = line.find(" ", type_start)
           
            # If no space is found, consider the type until the end of the line
            if type_end == -1:
                type_end = len(line)
           
            # Extract and add the type to the set
            item_type = line[type_start:type_end]
            currentsize = len(types)
            types.add(item_type)
            newsize = len(types)
            if (newsize>currentsize):
                typelines.add(line)
           
   
    return list(types)

with open("result1.txt", "r") as file:
    # Read the entire content of the file
    content = file.read()
# Split the content by "====="
#SHOW DIFFERENT TYPES for US to deal with
distinct_types = extract_distinct_types(content)

#print some header for code
print ("#!/usr/bin/env python")
print ("from gimpfu import *")




# example data of a section ============================================
# MAIN_NAME:svg:lighten
# PADS:pads: aux input output
# name: srgb type: boolean default: False
sections = content.split("=====")
print("#Distinct Types:", ",".join(distinct_types))
print("#Type Lines:", "\n#".join(typelines))
# Distinct Types: enum,pointer,color,double,string,seed,audiofragment,boolean,curve,path,uri,object,format,int,filepath
# Type Lines:
# name: space-name type: string  default: sRGB
# name: value type: double default: 0.00 minimum: -inf maximum: +inf ui-minimum: -1.00 ui-maximum: 1.00 ui-gamma: 1.00 ui-step-small: 0.00 ui-step-big: 0.10 ui-digits: 3
# name: background-color type: color default: rgba(0.000, 0.000, 0.000, 0.000) sensitive:! keep_surroundings role:color-secondary
# name: buffer type: object
# name: curve type: curve
# name: uri type: uri  default:
# name: audio type: audiofragment
# name: color-model type: enum
# name: seed type: seed
# name: subdivisions type: int default: 1 minimum: 0 maximum: 15 ui-minimum: 0 ui-maximum: 15 ui-gamma: 1.00 ui-step-small: 1 ui-step-big: 5
# name: buffer type: pointer
# name: path type: filepath  default:
# name: d type: path
# name: cpn-1-keep type: boolean default: False label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] rgb-label:Keep red component hsl-label:Keep hue component
# name: input-format type: format
#FUNCTION_NAME#
#VARIABLES# to pass into FUNCTION_NAME
    #GIMP_MESSAGES# if there's errors or unhandled/unimplemented cases
   
    #GEGLSTRINGLINE#
    #gegl_graph_string="#GEGL_STRING#"
   
    #GEGLCALLLINE#
    #pdb.python_fu_dinasset_gegl_graph(image, layer, gegl_graph_string)
#code_to_replaced_below
code = '''#---------------------------------------------------------------------------------------------
def #FUNCTION_NAME#(image, layer, #VARIABLES#):
#GIMP_MESSAGES#
    #GEGLSTRINGLINE#
    pdb.python_fu_dinasset_gegl_graph(image, layer, gegl_graph_string)
register(
    "python_fu_#FUNCTION_NAME#",
    "GEGL Testing",
    "GEGL Testing",
    "Auto Author",
    "Auto Author",
    "Auto Generated Dated",
    "<Image>/Python-Fu/GEGL-Automated/#FUNCTION_NAME_MENU#",             #Menu path
    "*",
    [
#PFVARIABLES#
    ],
    [],
    #FUNCTION_NAME#)
'''

#now we generate code here
for i in range(0,len(sections)):
    section = sections[i]
    lines = section.split("\n") #break each section into lines
    PFVARIABLES = []
    VARIABLES = []
    GIMP_MESSAGES = []
    function_name = ""
    GEGLSTRING = ""
    for j in range(0,len(lines)):
        spaceitems = lines[j].strip().replace("  "," ").split(" ") #replace double spaces with single spaces
        colonitems = lines[j].strip().replace("  "," ").split(":")
        if colonitems[0] == "MAIN_NAME":
            function_name = colonitems[1] + "_" + colonitems[2].replace("-","_") #so that MAIN_NAME:svg:lighten becomes "svg_lighten"
            GEGLSTRING += colonitems[1] + ":" + colonitems[2] + " "
            #print("MAIN_NAME FOUND" + function_name + "=>"+ GEGLSTRING)
        if spaceitems[0] == "PADS:pads:":
            pads = spaceitems[1:] #so that PADS:pads: aux input output becomes ["aux",input","output"]
            if len(pads) > 2:
                GIMP_MESSAGES.append("    pdb.gimp_message('Not Implemented for pads:"+",".join(pads)+"')");
        if spaceitems[0] == "name:": #parse variables name and types
            var_name = spaceitems[1] #Set variable name
            safe_var_name = var_name.replace('-', '_') #so python doesn't blow up
            #name: space-name type: string  default: sRGB
            if spaceitems[3] == "string":
                try:
                    default_value = spaceitems[5]
                except Exception as e: #if this fails we fall back on just minimum as maximum
                    default_value = ""   
                PFVARIABLES.append('    (PF_STRING, "'+safe_var_name+'", "'+var_name+':", "'+default_value+'")')
                GEGLSTRING += var_name + "=" + "%"+"s "
                VARIABLES.append(safe_var_name)
            #name: value type: double default: 0.00 minimum: -inf maximum: +inf ui-minimum: -1.00 ui-maximum: 1.00 ui-gamma: 1.00 ui-step-small: 0.00 ui-step-big: 0.10 ui-digits: 3
            elif spaceitems[3] == "double":
                default_value = float(spaceitems[5])
                try:
                    ui_minimum = spaceitems[11]
                    ui_maximum = spaceitems[13]
                except Exception as e: #if this fails we fall back on just minimum as maximum
                    ui_minimum = spaceitems[7]
                    ui_maximum = spaceitems[9]
                if ui_minimum == '-inf':
                    ui_minimum = -10000
                else:
                    ui_minimum = float(ui_minimum)   
                if ui_maximum == '+inf':
                    ui_maximum = 10000
                else:
                    ui_maximum = float(ui_maximum)       
                PFVARIABLES.append('    (PF_SPINNER, "'+safe_var_name+'", "'+var_name+':", '+str(default_value)+', ('+str(ui_minimum)+', '+str(ui_maximum)+', 0.1))')
                GEGLSTRING += var_name + "=" + "%"+"f "
                VARIABLES.append(safe_var_name)

            #name: background-color type: color default: rgba(0.000, 0.000, 0.000, 0.000) sensitive:! keep_surroundings role:color-secondary
            #name: buffer type: object
            #name: curve type: curve
            #name: uri type: uri  default:
            #name: audio type: audiofragment
            #name: color-model type: enum
            #name: seed type: seed
            #name: subdivisions type: int default: 1 minimum: 0 maximum: 15 ui-minimum: 0 ui-maximum: 15 ui-gamma: 1.00 ui-step-small: 1 ui-step-big: 5
            elif spaceitems[3] == "int":
                default_value = int(spaceitems[5])
                try:
                    ui_minimum = spaceitems[11]
                    ui_maximum = spaceitems[13]
                except Exception as e: #if this fails we fall back on just minimum as maximum
                    ui_minimum = spaceitems[7]
                    ui_maximum = spaceitems[9]
                if ui_minimum == '-inf':
                    ui_minimum = -10000
                else:
                    ui_minimum = int(ui_minimum)   
                if ui_maximum == '+inf':
                    ui_maximum = 10000
                else:
                    ui_maximum = int(ui_maximum)       
                PFVARIABLES.append('    (PF_SPINNER, "'+safe_var_name+'", "'+var_name+':", '+str(default_value)+', ('+str(ui_minimum)+', '+str(ui_maximum)+', 1))')
                GEGLSTRING += var_name + "=" + "%"+"d "
                VARIABLES.append(safe_var_name)
            #name: buffer type: pointer
            #name: path type: filepath  default:
            #name: d type: path
            #name: cpn-1-keep type: boolean default: False label:[color-model {rgb} : rgb-label, color-model {hsl} : hsl-label] rgb-label:Keep red component hsl-label:Keep hue component
            elif spaceitems[3] == "boolean":
                default_value = bool(spaceitems[5])
                PFVARIABLES.append('    (PF_TOGGLE, "'+safe_var_name+'","'+var_name+':",'+str(default_value)+')')
                GEGLSTRING += var_name + "=" + "%"+"d "
                VARIABLES.append(safe_var_name)
            #name: input-format type: format
            else:
                GIMP_MESSAGES.append("    pdb.gimp_message('Not Implemented for type:"+spaceitems[3]+"')");
                #TODO SHOW MESSAGE that it's not yet implemented
               
           
   
    VARIABLES = ",".join(VARIABLES)
    GEGLSTRINGLINE = ('gegl_graph_string="%s' % GEGLSTRING) + '" % (' + VARIABLES + ')';
    FUNCTION_NAME_MENU = function_name + "..."
    FUNCTION_NAME = function_name
    # print(VARIABLES)
    # print(GEGLSTRINGLINE)
    # print(FUNCTION_NAME)
    # print(FUNCTION_NAME_MENU)
    # print(PFVARIABLES)
    # Code Replacement here
    if function_name != "" and len(GIMP_MESSAGES) == 0: #only print some code if we actually have a function_name and there's no GIMP_MESSAGES to report
        newcode = code
        newcode = newcode.replace("#FUNCTION_NAME#",FUNCTION_NAME)
        newcode = newcode.replace("#FUNCTION_NAME_MENU#",FUNCTION_NAME_MENU)
        newcode = newcode.replace("#VARIABLES#",VARIABLES)
        newcode = newcode.replace("#GEGLSTRINGLINE#",GEGLSTRINGLINE)
        newcode = newcode.replace("#PFVARIABLES#",",\n".join(PFVARIABLES))
        newcode = newcode.replace("#GIMP_MESSAGES#","\n".join(GIMP_MESSAGES))
        print(newcode)
#call main to close off the code
print("main()")
#(PF_INT, "p0", "_INT:", 0), # PF_INT8, PF_INT16, PF_INT32  similar but no difference in Python.
#           (PF_FLOAT, "p02", "_FLOAT:", 3.141),
#           (PF_STRING, "p03", "_STRING:", "foo"),  # alias PF_VALUE
#           (PF_TEXT, "p04", "TEXT:", "bar"),
#           # PF_VALUE
#           # Pick one from set of choices
#           (PF_OPTION,"p1",   "OPTION:", 0, ["0th","1st","2nd"]), # initially 0th is choice
#           (PF_RADIO, "p16", "RADIO:", 0, (("0th", 1),("1st",0))), # note bool indicates initial setting of buttons
#           # PF_RADIO is usually called a radio button group.
#           # SLIDER, ADJUSTMENT types require the extra parameter of the form (min, max, step).
#           (PF_TOGGLE, "p2",   "TOGGLE:", 1), # initially True, checked.  Alias PF_BOOL
#           # PF_TOGGLE is usually called a checkbox.
#           (PF_SLIDER, "p3", "SLIDER:", 0, (0, 100, 10)),
#           (PF_SPINNER, "p4", "SPINNER:", 21, (1, 1000, 50)),  # alias PF_ADJUSTMENT
#           # Pickers ie combo boxes ie choosers from lists of existing Gimp objects
#           (PF_COLOR, "p14", "_COLOR:", (100, 21, 40) ), # extra param is RGB triple
#           # PF_COLOUR is an alias by aussie PyGimp author lol
#           (PF_IMAGE, "p15", "IMAGE:", None), # should be type gimp.image, but None works
#           (PF_FONT, "p17", "FONT:", 0),
#           (PF_FILE, "p18", "FILE:", 0),
#           (PF_BRUSH, "p19", "BRUSH:", 0),
#           (PF_PATTERN, "p20", "PATTERN:", 0),
#           (PF_GRADIENT, "p21", "GRADIENT:", 0),
#           (PF_PALETTE, "p22", "PALETTE:", 0),
#           (PF_LAYER, "p23", "LAYER:", None),
#           (PF_CHANNEL, "p24", "CHANNEL:", None),  # ??? Usually empty, I don't know why.
#           (PF_DRAWABLE, "p25", "DRAWABLE:", None),
#           # Mostly undocumented, but work
#           (PF_VECTORS, "p26", "VECTORS:", None),
#           (PF_FILENAME, "p27", "FILENAME:", 0),
#           (PF_DIRNAME, "p28", "DIRNAME:", 0)
#           # PF_REGION might work but probably of little use.  See gimpfu.py.


attached file is the generated py code to expose gegl functions.
There are right now 72 exposed.

If I learn more in the future about how to map params and deal with other "pads" I'll add changes to above code to generate more.

When I generated all of them an put gimp messages to say "Not Yet Implemented" I ran into an issue when the file is too large GIMP wouldn't load so I had to break it into 2 files about 3000 lines each then GIMP was happy with it (I don't know what the real limit is though).

But yeah this one is small enough to have in one file that exposes all 72 functions basically any functions that uses "string","int","double","boolean" and has pads 2 or less pads.

Oh yeah you have to look at the first post and uncomment dinnaset register call (that's currently being commented out) because this uses that.

See friendlier labelled version (of gegl-python-fu.zip)

Re: GEGL operations exposed to Python-Fu - WIP

Mon Nov 06, 2023 11:17 am

LOTS HAVE BEEN EXPOSED currently 72 functions (files in previous post).

I tried the bloom and something happened/changed result so I guess that's good.

Image

Re: GEGL operations exposed to Python-Fu - WIP 72 exposed

Mon Nov 06, 2023 11:37 am

I am on Windows so I don't know Linux peeps can use this or not
paynekj is the real hero here exposing the ability to call gegl with string to dinasset.
Now I am hoping paynekj knows how to or can instruct me on how to call functions that have more than 2 pads (mentioned in gegl operations descriptions).
and/or and how to deal with other variable types as well (other than "int","double","string","boolean").

Re: GEGL operations exposed to Python-Fu - WIP 72 exposed

Mon Nov 06, 2023 11:56 am

Love to hear back from people who successfully uses these front-end or from python-fu.

Re: GEGL operations exposed to Python-Fu - WIP 72 exposed

Mon Nov 06, 2023 2:36 pm

Test running lines of code from python-fu like this and it worked
Code:
pdb.python_fu_gegl_bloom(image,layer,50,25,10,50,1)
pdb.python_fu_gegl_cartoon(image,layer,7.0,0.2)

the effect will be applied on layer or selection of layer (if there is selection present).

Re: GEGL operations exposed to Python-Fu - WIP 72 exposed

Mon Nov 06, 2023 2:37 pm

Where's the man at? Kevin?

Re: GEGL operations exposed to Python-Fu - WIP 72 exposed

Mon Nov 06, 2023 3:15 pm

Image
This is friendlier labels when run from front end or browsing in procedure browser
as it shows default value and min..max right in brackets ie (default: 1, 0..50)

Re: GEGL operations exposed to Python-Fu - WIP 72 exposed

Mon Nov 06, 2023 11:49 pm

I was bored and thought it would be fun to generate some static color 2 gray (c2g)
and let people browse by clicking to get a good feel of what the values do as they change.
You get to see different values at the same time so it's kind'a cool
https://tinmantaken.blogspot.com/2023/1 ... tions.html

Re: GEGL operations exposed to Python-Fu - WIP 72 exposed

Mon Nov 06, 2023 11:53 pm

Tin, see my post on the other thread.

Re: GEGL operations exposed to Python-Fu - WIP 72 exposed

Tue Nov 07, 2023 12:06 am

dinasset wrote:Tin, see my post on the other thread.

It's done here

Re: GEGL operations exposed to Python-Fu - WIP 72 exposed

Tue Nov 07, 2023 4:20 am

Interesting plugins, I love experimenting.

I did find one that locked-up, GEGL tiles. I thought it might be me, so tried again and....

System Warning, running out of space in my home partition (kubuntu 20.04) this is filelight.

gegl.jpg
gegl.jpg (42.5 KiB) Viewed 39985 times


Not a problem, just emptied ~/.cache, as long as you know where to look ;)

Re: GEGL operations exposed to Python-Fu - WIP 72 exposed

Tue Nov 07, 2023 6:33 am

rich,
I tried it tile and it just ate up the image like blank it (completely transparent) out on mine. I am on windows.

Re: GEGL operations exposed to Python-Fu - WIP 72 ops wrapped

Tue Nov 07, 2023 9:22 am

Tim,
Thank you for the very useful plug-in. In GIMP 2.10, GEGL operations when run from Python can be flakey, so your plug-in will reduce some self doubt and prove to be an excellent research tool for me. :yes

Re: GEGL operations exposed to Python-Fu - WIP 72 ops wrapped

Tue Nov 07, 2023 10:02 am

vit, do you have the latest 2 files?
as dinasset requested the name change to remove dinasset from the function call so it needs the other gegl_graph.py included with that last zip (download/file.php?id=69700)

Re: GEGL operations exposed to Python-Fu - WIP 72 ops wrapped

Tue Nov 07, 2023 12:30 pm

Tin, sorry I can't help.

I gave up on this quite soon after starting when I found that there's no way to pass curve arrays into GEGL: https://gitlab.gnome.org/GNOME/gegl/-/issues/264

Kevin
Post a reply