From: Jair Trejo on
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
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

> > 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/