Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Automation questions.
#1
Hello,

I am using Python 3 to edit some images successfully using PIL, but there are things that I'm unable to do with it and was hoping to call gimp from python for those specific tasks.

What I'm currently manually doing in GIMP and need to automate is:
1. Open Image
2. Select by color
3. Shrink selection
4. Select > To path
5. Export path.. [as svg] (accessing the svg information without saving the file would also work)

From what little I could see in the python console inside GIMP the following procedures can be scripted that seem to match the above requirements, though I wouldn't know how to do so yet:
1. file-png-load
2. gimp-image-select-color
3. gimp-selection-shrink
4. plug-in-sel2path
5. Can't find any.


What would be the best way to automate this process from the command line?

Thank you,
Nick
Reply
#2
For a general way to call Python scripts in batch, see here.

There is no API to export paths as SVG, but the path data is easy to obtain. See here for my collection of path-related scripts, in particular path-csv that imports/exports the path contents from/to a CSV file.

Also some background on paths with a Gimp perspective here.
Reply
#3
(10-10-2019, 07:07 AM)Ofnuts Wrote: For a general way to call Python scripts in batch, see here.

There is no API to export paths as SVG, but the path data is easy to obtain. See here for my collection of path-related scripts, in particular path-csv that imports/exports the path contents from/to a CSV file.

Also some background on paths with a Gimp perspective here.

Thank you for the prompt and informative answer!

I have created the following plugin and managed to export the information I need to use within python:

Code:
#!/usr/bin/env python

from gimpfu import *


def green_path(wall_color, image_file):
   image = pdb.gimp_file_load(image_file, image_file)
   drawable = pdb.gimp_image_get_active_drawable(image)
   pdb.gimp_image_select_color(image, 0, drawable, wall_color)
   pdb.gimp_selection_shrink(image, 4)
   pdb.gimp_selection_sharpen(image)
   pdb.plug_in_sel2path(image, drawable)
   active_vectors = pdb.gimp_image_get_active_vectors(image)
   vector_string = pdb.gimp_vectors_export_to_string(image, active_vectors)

   return pdb.gimp_message(vector_string)


register(
   "python-fu-green-path",
   "Green walls to path",
   "Converts green walls into a path",
   "Nicolas San Martin", "Nicolas San Martin", "2019",
   "Green walls to path",
   "",
   [
       (PF_STRING, "wall_color", "Color of the walls to be converted", None),
       (PF_FILE, "image_file", "Path to the Mask Dungeon (70px)", None)
   ],
   [],
   green_path, menu="<Image>/Tools")

main()

The only problem I seem to be having now is that it creates a lot of nodes. It's not a problem with the script but how GIMP creates the path based on the selection. Using an image such as this one and selecting the green "walls" in the dungeon, it generates two parallel paths based on the edges of the selection. I have attached two example output .svg files with 0px and 4px shrinking.

Is there any way to generate a single path/line in the middle of the selection? (I don't need it to be perfect, the path should be formed as series of narrow straight lines going through the middle of the green wall to use as few nodes as possible).

Thank you!


Attached Files
.svg   full.svg (Size: 76.27 KB / Downloads: 2)
.svg   shrunk_4px.svg (Size: 84.07 KB / Downloads: 3)
Reply
#4
Not with Gimp, but there is a "centerline" plugin for Inkscape.
Reply
#5
Some alternatives.

Inkscape uses Autotrace for the center-line trace extension. For autotrace see: https://github.com/autotrace/autotrace

Gets a result like this. https://i.imgur.com/ak28rHc.jpg There is a warning about image size and scaling. Stroked same size as original line.

There is a Gimp plugin trace.py that uses autotrace for a centerline trace see: https://gimpchat.com/viewtopic.php?f=9&t=17485

Autotrace on its own is very quick, but here (kubuntu 18.04) I have to use bmp format (without colour info ) for input.
Code:
autotrace -color-count 2 -centerline -corner-threshold 60 -output-format svg -output-file out.svg -report-progress new.bmp

Never going to be very precise. This comparing trace.py and autotrace CL: https://i.imgur.com/Qqrw0Dk.jpg Of course there are parameters that can be tweaked if you have the time/patience.
Reply
#6
Thank you both for the replies and information. In the end, since these .svg paths are supposed to fit on a grid, I managed to solve the problem by moving every node to the nearest vertex in that 70px grid with a bit of regex (after changing what is selected as well for fewer nodes). I first separate the path coordinates from the rest of the file, and then run a function for each number found in there to translate that node into the vertex:

Code:
coordinates = re.search(r' d="(.+?) Z" />', vector_string.stderr, re.S).group(1)
coordinates = re.sub(r"\d+.\d+", lambda exp: str(round(float(exp.group()) / 70) * 70.0) + '0', coordinates)

With that I ended up with perfectly straight lines right in the center. I have attached a before and after svg to this post (v1 and final respectively) to see the difference.

There are fewer nodes now than before (about half), but still more than needed. As you can see in the examples, there will be 'corners' where up to 5 nodes converge, and only 1 is needed. In the end it will look the same, but since these will be used on a web application that computes lighting based on the path, the extra nodes will take their toll. I'm trying to deduplicate those, but I'm having trouble understanding exactly what I should be checking for in the file for that.

As an example, in the image below you will see 4 points where multiple nodes converge. Only a few nodes will actually form a path that isn't towards the same point of origin (A-D, F-J, L-M), the rest are essentially useless (G-H for example, originates and ends in the same place). I need to remove those without accidentally removing a node that actually goes somewhere forming a visible path. For that I need to understand how GIMP organizes or chains these nodes to form a path.

[Image: b3XOxa2.jpg]

In the 'final' svg you can see near the beginning several 910.00,910.00, also towards the end. How many am I safe to remove?

My thinking is no set of 2 numbers (separated by a comma) should repeat next to an equal set, and that should be enough to remove all duplicates, but I'm not sure. I ramble, and hope you can understand my musings; I would appreciate any insight you may have on this.

Cheers!


Attached Files
.svg   svg_example_v1.svg (Size: 18.34 KB / Downloads: 6)
.svg   svg_example_final.svg (Size: 18.33 KB / Downloads: 4)
Reply
#7
"Converge" is not really the word... It just that instead of having  as single point you have several consecutive identical points. In the path editor, when you drag an anchor at a  corner, you see another anchor remaining at the same spot, and if you drag it, there will also be another anchor remaining...

So you can fix this by walking the path, and removing all triplets where the anchor is at the same coordinates as the previous one.

Once this is done you can further simplify the path because because there are anchors that serve no purpose in the middle of straight lines. To clean them, consider 3 consecutive anchors, a,b,c. If (xc-xa)/(yc-ya)==(xb-xa)/(yb-ya) then b can be dropped (IRL you have of course to consider the case where yc==ya or yb==ya to avoid division by zero, but if yc==yb==ya then they are aligned).

Last, the last anchors of your strokes have the same coordinates as the first. This is not necessary since the stroke is "closed".
Reply


Forum Jump: