Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Gimp, Python versions, and flatpak
#1
I've been writing a python plugin for gimp, using RC2 installed with flatpak.  It's been a steep learning curve but i have it working.
I now want to take some of that code and put it in a standalone python app, since it doesn't actually need the gimp interface

My idea was to simply use the system python and import the necessary gi repository files - but they are already installed inside the flatpak

Is there a way to use the python version installed with gimp and flatpak from outside the flatpak sandbox?
Or should I copy the gi repository files into the system python directories, and if so where?

Many thanks
Reply
#2
(copied my answer from the question elsewhere)

You can't do this. Your Python code relies on the whole Gimp executable for most of its functionality. The gi repos are merely interfaces to code in Gimp, Gegl and Babl. In fact the code in the Gimp import only works when its caller (your code) is called from Gimp... You could have more luck with just Gegl/Babl.

You can run Gimp without a UI (-i, --no-interface) and it is likely possible to run flatpak-Gimp in batch mode (even if the start incantation is likely a bit different). But installing Gimp form a .deb would be a lot easier, and .deb Babl/Gegl would be a requirement if you can skirt Gimp. You can get 3.00 RC2 in .deb format from here: https://launchpad.net/~mati75/+archive/ubuntu/gimp30

But very often, I see people writing very complicated scripts around Gimp to do rather simple things that are better done with shell scripts around ImageMagick or with Python and image processing libraries (pillow, openCV...).
Reply
#3
Im sorry to have made you repeat yourself - I did find this answer eventually.  I've tried running a simple batch process by loading a 'hello world' script into the scripts directory and starting it with 


Code:
flatpak run  org.gimp.GIMP//beta --batch-interpreter python-fu-eval -i -b 'hello' --verbose


This fires up the script interpreter ok, but then fails with the error message:
Code:
GIMP-Error: Unable to run plug-in "hello.py"
(/home/chris/.config/GIMP/3.0/plug-ins/hello/hello.py)

Failed to execute child process “/home/chris/.config/GIMP/3.0/plug-ins/hello/hello.py” (Exec format error)

The plugin code:
Code:
#!/usr/bin/env python3

def run():
   print("Hello World!")

if __name__ == "__main__":
   print "Running as __main__ with args: %s" % sys.argv
   run()

which I thought should run since its running as a batch process.  

What I discovered does work is 
Code:
flatpak run  org.gimp.GIMP//beta --batch-interpreter python-fu-eval -i -b 'print("hello")'
hello
batch command executed successfully


so it looks as if the -b instruction is passing the argument directly to the interpreter, not treating it as a file name.


I'm stuck now.  I appreciate your suggestion that there might be simpler ways of doing what I'm trying to do, but to be honest I'm so nearly finished it seems a waste to start again.  Just need to get over this last hurdle!
Reply
#4
See https://stackoverflow.com/questions/4443...0#44435560
Reply
#5
Thanks for all your help with this.  I have it working nicely now.  The full setup is I have a script that watches for changes in a mailbox, downloads incoming files and strips off any attachments.  When it has found a new image it calls the batch file to process this image - basically resize it and put it into a mask (premade templat.xcf) to print out a badge.  The xcf file is then saved so that a user can open it, slide the image around in the mask, resize if necessary, and print.  

Just so that others have some more code samples for gimp 3.0 I'll upload the key section here and hope this helps someone else.  Thanks again

Code:
for fname in glob.glob(os.path.join(imagepath, '*.*')):
           Gimp.message('get the template file')
           tfile = Gio.File.new_for_path(os.path.join(templatepath, 'template.xcf'))
           Gimp.message('build an image from the file')
           timage = Gimp.file_load(Gimp.RunMode.NONINTERACTIVE, tfile)
           Gimp.message('get the group layer of the template')
           tgroup = timage.get_layers()[0]
           Gimp.message(fname)
           f = Gio.File.new_for_path(fname)
           Gimp.message('build a work image')
           work_im = Gimp.file_load(Gimp.RunMode.NONINTERACTIVE, f)
           h = Gimp.Image.get_height(work_im)
           Gimp.message('here')
           w = Gimp.Image.get_width(work_im)
           if h < 600 or w < 600:
               pass
           else:
               height = 600
               width = w / (h / 600)
           Gimp.Image.scale(work_im, int(width), int(height))
           Gimp.message('get background layer from the work image')
           layer = work_im.get_layers()[0]
           Gimp.message('create a layer for the template')
           # copy to template
           tlayer = Gimp.Layer.new_from_drawable(layer, timage)
           Gimp.message('set to intersection')
           Gimp.Layer.set_composite_mode(tlayer, Gimp.LayerCompositeMode.INTERSECTION)
           Gimp.message('rename the layer')
           fname, file_extension = os.path.splitext(os.path.basename(fname))
           Gimp.message(fname)
           Gimp.Item.set_name(tlayer, fname)
           # Gimp.Item.set_name(timage, fname)
           Gimp.message('add the intersect layer to the group')
           Gimp.Image.insert_layer(timage, tlayer, timage.get_layers()[0], 1)
           # should be view circle, image, inner circle
           #Gimp.Display.new(timage) - this is now called interactively so there is no display
           Gimp.Image.delete(work_im)
           Gimp.file_save(Gimp.RunMode.NONINTERACTIVE, timage,
                          Gio.File.new_for_path(os.path.join(imagepath, 'waiting/', fname + '.xcf')))
Reply


Forum Jump: