RSS/Atom feed Twitter
Site is read-only, email is disabled

Gimp choking on python invocation

This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.

This is a read-only list on gimpusers.com so this discussion thread is read-only, too.

5 of 6 messages available
Toggle history

Please log in to manage your subscriptions.

Gimp choking on python invocation Vio 19 Nov 21:54
  Gimp choking on python invocation Jon Nordby 19 Nov 23:04
   CABX3TwDf8p2WcJcZmjFF4d7dCA... 20 Nov 13:52
    Gimp choking on python invocation Vio 20 Nov 13:51
     Gimp choking on python invocation Vio 21 Nov 19:21
  Gimp choking on python invocation Ofnuts 19 Nov 23:21
Vio
2012-11-19 21:54:12 UTC (over 12 years ago)

Gimp choking on python invocation

Hello,
Newcomer on this list but old time python coder with a Gimp itch someone might have an idea how to scratch. Task seem simple enough: make Gimp do some back-flips from afar through snaky incantations ... This imply combining 2 libs: gimpfu and xmlrpc. Well, after a sleepless night trying to solve this query, I am almost ready to give up.
so I feel ready to get enlightened. I'm most probably doing something stupid someplace,
but I need another pair of eyeballs to put me on the right track to see my error.

My simple test-case below, followed by some simple test output I get. I'm on ubuntu, my gimp is 2.6.8, python version is ... whatever is embedded there

------------------------------------------------------- #! /usr/bin/env python
from gimpfu import *

# xmlrpc
from SimpleXMLRPCServer import SimpleXMLRPCServer from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler # Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler): print 'TRACE> RequestHandler()'
rpc_paths = ('/RPC2',)
# Create server
server = SimpleXMLRPCServer(("localhost", 8000), allow_none=True)

def echo(*args): print "echo:", args
server.register_function(echo, 'myecho')

def farmsg(msg): return 'farmsg is: %s' % msg
server.register_function(farmsg)

def pixh(*args): print "args:", args
src_path = args[0]
print 'pixh src>%s%d%d entering main()' main()

print 'TRACE> entering serve_forever()' server.serve_forever()

------------------------------------------------------------------ Some output I'm getting (or lack of)

STARTING SERVER WITH: gimp --no-interface --batch '(python-fu-clientecho RUN-NONINTERACTIVE "/tmp/t/rihanna.jpg")' &

TALKING TO SERVER WITH (xmlrpc server seem to work Ok, it's the Gimp which fails below):

import xmlrpclib
s = xmlrpclib.ServerProxy('http://localhost:8000')

TRACE> RequestHandler()
TRACE> entering main()
TRACE> entering serve_forever()

s.myecho('sssssssss')

$ echo: ('sssssssss',)

s.farmsg('homeeeer')

'farmsg is: homeeeer'

s.pixh('/tmp/t/rihanna.jpg')

pixh src>/tmp/t/rihanna.jpg<
... then nothing

My understanding is that Gimp chokes on this code for some unknown reason. Perhaps I am not invoking it correctly? Killing a Gimp child gaves some error message: GIMP-Error: Opening '/dd/d/devel.../MY/(gimp-quit 1)' failed: No such file or directory
So I removed the '(gimp-quit 1)' startup invocation... That error dissapeared, but so did Gimp's conversational skills...

I know what you're saying: by now I should just start learning Scheme and use extrans/gimpclient.py
to send Scheme instructions to the embedded Gimp-server. But my question is: why can't I invoke gimp-python remotely as the scheme crowd can? Where am I putting my foot in my mouth in this code? I know others have solved this puzzle, as I see a few web-apps using gimp as their graphics workhorse.
But can it be solved in python alone (no scheme)?

PS. if this has been answered before elsewhere, a link to that post would be most appreciated.
But I've googled this topic non-stop for over 24 hours straight now, with no luck. Not expecting miracles. Anyway, any suggestion very welcome ;)

Cheers! zaz

Jon Nordby
2012-11-19 23:04:59 UTC (over 12 years ago)

Gimp choking on python invocation

On 19 November 2012 22:54, Vio wrote:

print 'TRACE> entering serve_forever()' server.serve_forever()

This script will not return control back to GIMP, so the application probably cannot continue past the loading of this script. You will need to do this in an async fashion. You can try to register a glib timeout/idle handler, though I am not sure if it will work.

Jon Nordby - www.jonnor.com
Ofnuts
2012-11-19 23:21:19 UTC (over 12 years ago)

Gimp choking on python invocation

On 11/19/2012 10:54 PM, Vio wrote:

Hello,
Newcomer on this list but old time python coder with a Gimp itch someone might have an idea how to scratch. Task seem simple enough: make Gimp do some back-flips from afar through snaky incantations ... This imply combining 2 libs: gimpfu and xmlrpc. Well, after a sleepless night trying to solve this query, I am almost ready to give up.
so I feel ready to get enlightened. I'm most probably doing something stupid someplace,
but I need another pair of eyeballs to put me on the right track to see my error.

My simple test-case below, followed by some simple test output I get. I'm on ubuntu, my gimp is 2.6.8, python version is ... whatever is embedded there

------------------------------------------------------- #! /usr/bin/env python
from gimpfu import *

# xmlrpc
from SimpleXMLRPCServer import SimpleXMLRPCServer from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler # Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler): print 'TRACE> RequestHandler()' rpc_paths = ('/RPC2',)
# Create server
server = SimpleXMLRPCServer(("localhost", 8000), allow_none=True)

def echo(*args): print "echo:", args
server.register_function(echo, 'myecho')

def farmsg(msg): return 'farmsg is: %s' % msg
server.register_function(farmsg)

def pixh(*args): print "args:", args
src_path = args[0]
print 'pixh src>%s%d%d entering main()' main()

print 'TRACE> entering serve_forever()' server.serve_forever()

------------------------------------------------------------------ Some output I'm getting (or lack of)

STARTING SERVER WITH: gimp --no-interface --batch '(python-fu-clientecho RUN-NONINTERACTIVE "/tmp/t/rihanna.jpg")' &

TALKING TO SERVER WITH (xmlrpc server seem to work Ok, it's the Gimp which fails below):

import xmlrpclib
s = xmlrpclib.ServerProxy('http://localhost:8000')

TRACE> RequestHandler()
TRACE> entering main()
TRACE> entering serve_forever()

s.myecho('sssssssss')

$ echo: ('sssssssss',)

s.farmsg('homeeeer')

'farmsg is: homeeeer'

s.pixh('/tmp/t/rihanna.jpg')

pixh src>/tmp/t/rihanna.jpg<
... then nothing

My understanding is that Gimp chokes on this code for some unknown reason. Perhaps I am not invoking it correctly? Killing a Gimp child gaves some error message: GIMP-Error: Opening '/dd/d/devel.../MY/(gimp-quit 1)' failed: No such file or directory
So I removed the '(gimp-quit 1)' startup invocation... That error dissapeared, but so did Gimp's conversational skills...

I know what you're saying: by now I should just start learning Scheme and use extrans/gimpclient.py
to send Scheme instructions to the embedded Gimp-server. But my question is: why can't I invoke gimp-python remotely as the scheme crowd can? Where am I putting my foot in my mouth in this code? I know others have solved this puzzle, as I see a few web-apps using gimp as their graphics workhorse.
But can it be solved in python alone (no scheme)?

PS. if this has been answered before elsewhere, a link to that post would be most appreciated.
But I've googled this topic non-stop for over 24 hours straight now, with no luck. Not expecting miracles. Anyway, any suggestion very welcome ;)

Cheers! zaz
_______________________________________________ gimp-developer-list mailing list
gimp-developer-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gimp-developer-list

To expand on Jon's answer, I believe that what you want to do is doable, but a bit differently. You have to start Gimp as if running in batch mode, specifying a Python script to initiate. This script (that doesn't need to register, and shouldn't do so) should then be able to run your processing loop.

Vio
2012-11-20 13:51:59 UTC (over 12 years ago)

Gimp choking on python invocation

Jon and Ofnuts, thanks for your feedback. Much appreciated!

Guys, I think you got it the other way around:

First, it's my script which should be in control, not Gimp,

Second, when I tell Gimp -----------------
img = pdb.file_jpeg_load(src_path, 1) -----------------
I expect Gimp to open that image, then return back control to my script with an image handler/reference stored in "img".

My problem is that Gimp does "not" do what the script says: at that precise line, Gimp takes control, and does NOT give it back (!!),
(from what I could see so far)
nor does Gimp tell me what's wrong with some meaningful error msg. So it's not some complicated script, this is very simple stuff. Up to that line, everything rocks, and the other lib (xmlrpc) seem to work as expected (yeee!).

My problem is with Gimp not behaving and being silent about it !!

Obviously Gimp does not like xmlrpc for some reason, because when I execute that script without the xmlrpc part, everything rocks.
Worst is probably the "failing silently" part: I have no idea what Gimp does not like about xmlrpc's presence in my script... does Gimp log errors somewhere? I could not find gimp error logs on my system so far (I'm on ubuntu)

Anyway, thanks for your kind suggestions guys. Much appreciated! vio

PS. Jon, after re-reading your post, I reiterate: yes, script loads OK, and executes Ok. Up to the Gimp line:
-----------------
img = pdb.file_jpeg_load(src_path, 1) -----------------
I'm assuming this because I get "print" msgs up to that point, and nothing after that. So I'm guessing it's a Gimp problem. Why does Gimp choke on that line?? Couldn't figure it out yet...

On Mon, Nov 19, 2012 at 6:04 PM, Jon Nordby wrote:

On 19 November 2012 22:54, Vio wrote:

print 'TRACE> entering serve_forever()' server.serve_forever()

This script will not return control back to GIMP, so the application probably cannot continue past the loading of this script. You will need to do this in an async fashion. You can try to register a glib timeout/idle handler, though I am not sure if it will work.

-- Jon Nordby - www.jonnor.com

Vio
2012-11-21 19:21:56 UTC (over 12 years ago)

Gimp choking on python invocation

Hey guys,
Small follow-up to close my issue.

First thanks to everyone for your kind help. Second, while I haven't solved it the way I want it, I went for the fast and easy path: talk to the gimp-server in scheme

Here's my little contribution to this discussion, code-wise. It's a compacted client (30-something lines of code) modified from elsewhere, adapted to my needs. Also because I like small ... small is beautiful ;) It does not mingle with gimp directly because I could not solve that issue So talking to the gimp from afar: sockets

-- my_gimp_client.py ---------------------------- import struct, socket, os, time
def strtogimp(s): return 'G'+struct.pack("!h", len(s))+s def do(cmd):
gs.send(strtogimp(cmd))
data=""
while len(data) < 4: data = data + gs.recv(1024) mlen = struct.unpack("!h",data[2:4])[0] while len(data) < mlen+4: data = data + gs.recv(1024) file('/tmp/t/DATA_received_gimp','a').write('%s/n/n' % data) if data[1]=='\001': raise RuntimeError(data[4:]) else: return data[4:]
# STARTUP
print"""gimp --no-interface -b '(plug-in-script-fu-server 1 10008 "/tmp/t/gimp.log")'&"""
os.system(
"""gimp --no-interface -b '(plug-in-script-fu-server 1 10008 "/tmp/t/gimp.log")'&""")
print 'sleep 12... gimp waking up ...' time.sleep(12) #gimp wakes up: 10sec isn't enough, but 12sec is (on my box) gs = socket.socket(socket.AF_INET, socket.SOCK_STREAM) gs.connect(('localhost', 10008))
print 'connection:',gs.getpeername() #just making sure we are in business # WORK
print 'work...'
work3 = """
(define inpath "/tmp/t/rihanna.jpg") (define outpath "/tmp/t/%d.jpg")
(define img (car (gimp-file-load RUN-NONINTERACTIVE inpath inpath))) (gimp-image-get-name img)
(gimp-image-flatten img)
(define drawable (car (gimp-image-get-active-drawable img))) (gimp-file-save RUN-NONINTERACTIVE img drawable outpath outpath) """ # sorry for my Scheme code, just learned this thing since yesterday ... and it shows ha...
gs.send(strtogimp(work3 % int(time.time()))) #customizing the scheme script the silly way
print 'work ... sleep 2...'
time.sleep(2) # wait for the gimp to do its magic # EXIT
print 'exit...'
gs.send(strtogimp('(gimp-quit 0)'))
gs.close()
os.system('ls /tmp/t') #checking out the result -- /my_gimp_client.py ----------------------------

this code works on my box, hope you might find it useful. obviously don't use it in production, but could be a nice starting point for experimenting...

Keep the excellent Gimp work going guys!! cheers!
vio