Prev: how to pass parameter to a python script when running it in theinteractive shell?
Next: flatten sequences in a dictionary
From: Jair Trejo on 1 Jan 2008 20:14 I'm doing some image processing in PIL, and I want to display the results in a GTK window using PyCairo, so I create a Cairo image surface from the PIL Image like this: mfile = StringIO.StringIO() final.save(mfile, format="PNG") ima = cairo.ImageSurface.create_from_png(mfile) mfile.close() return ima Where final is a PIL image. The problem is, I get a IOError: error while reading from Input Stream. �Any idea of why is this happening? I tried saving to a temporary file, i.e., replace the above code with: final.save('final.png') ima = cairo.ImageSurface.create_from_png('final.png') Instead of a StringIO object, and it works just fine. ____________________________________________________________________________________ �Capacidad ilimitada de almacenamiento en tu correo! No te preocupes m�s por el espacio de tu cuenta con Correo Yahoo!: http://correo.yahoo.com.mx/
From: Fredrik Lundh on 2 Jan 2008 09:39 Jair Trejo wrote: > I'm doing some image processing in PIL, and I want to > display the results in a GTK window using PyCairo, so > I create a Cairo image surface from the PIL Image like > this: > data > mfile = StringIO.StringIO() > final.save(mfile, format="PNG") > ima = > cairo.ImageSurface.create_from_png(mfile) > mfile.close() > return ima > > Where final is a PIL image. The problem is, I get a > IOError: error while reading from Input Stream. > > �Any idea of why is this happening? "save" leaves the file pointer at an undefined position (usually at the end), so my guess is that you have to rewind the file before you pass it to the next function: final.save(mfile, format="PNG") mfile.seek(0) # rewind also note that compressing and decompressing will introduce unnecessary overhead; chances are that you might get a lot better performance if you just shuffle the raw pixels. I haven't used PyCairo myself, but from a quick look at the ImageSurface documentation, something like this should work (untested): if final.mode != "RGB": final = final.convert("RGB") w, h = final.size data = final.tostring() # get packed RGB buffer ima = cairo.ImageSurface.create(data, FORMAT_RGB24, w, h, w*3) (tweak as necessary) </F>
From: Jair Trejo on 2 Jan 2008 14:19
> > De: Fredrik Lundh <fredrik(a)pythonware.com> > A: python-list(a)python.org > Fecha: Wed, 02 Jan 2008 15:39:11 +0100 > Asunto: Re: PyCairo, PIL and StringIO > > Jair Trejo wrote: > > > I'm doing some image processing in PIL, and I want > to > > display the results in a GTK window using PyCairo, > so > > I create a Cairo image surface from the PIL Image > like > > this: > > data > > mfile = StringIO.StringIO() > > final.save(mfile, format="PNG") > > ima = > > cairo.ImageSurface.create_from_png(mfile) > > mfile.close() > > return ima > > > > Where final is a PIL image. The problem is, I get > a > > IOError: error while reading from Input Stream. > > > > �Any idea of why is this happening? > > "save" leaves the file pointer at an undefined > position (usually at the > end), so my guess is that you have to rewind the > file before you pass it > to the next function: > > final.save(mfile, format="PNG") > mfile.seek(0) # rewind > > also note that compressing and decompressing will > introduce unnecessary > overhead; chances are that you might get a lot > better performance if you > just shuffle the raw pixels. I haven't used PyCairo > myself, but from a > quick look at the ImageSurface documentation, > something like this should > work (untested): > > if final.mode != "RGB": > final = final.convert("RGB") > w, h = final.size > data = final.tostring() # get packed RGB buffer > ima = cairo.ImageSurface.create(data, > FORMAT_RGB24, w, h, w*3) > > (tweak as necessary) > > </F> Thank, you, it worked! I tried rewinding the file, and it worked OK. But you were right about performance issues, so I tweaked your code and left it as: from array import array .... w,h = final.size data=array('c') data.fromstring(final.tostring()) ima=cairo.ImageSurface.create_for_data(data, cairo.FORMAT_ARGB32,w,h,w*4) return ima Which is around 10 times faster. The problem is, it swaps the R and B bands. I could probably write my own Image.tostring(), but i found it more convenient to swap the channels before processing, and it worked just fine. ____________________________________________________________________________________ �Capacidad ilimitada de almacenamiento en tu correo! No te preocupes m�s por el espacio de tu cuenta con Correo Yahoo!: http://correo.yahoo.com.mx/ |