Semo
Semo

Reputation: 821

How to save PIL.ImageTk.PhotoImage as jpg

I would like to save a PIL.ImageTk.PhotoImage into a file. My approach is to create a file "with open" and call the "write" method, but it wont't work, because I don't know how to get the byte-array from the object.

def store_temp_image(data, image):
    new_file_name = data.number + ".jpg"
    with open(os.path.join("/tmp/myapp", new_file_name), mode='wb+') as output:
        output.write(image)

The error message is as follows:

TypeError: a bytes-like object is required, not 'PhotoImage'

I usually find approaches to convert ImageTk Objects into PIL objects, but not the other way round. From the docs I couldn't get any hints neither.

Upvotes: 3

Views: 4642

Answers (3)

Harry K.
Harry K.

Reputation: 640

You can first use the ImageTk.getimage() function (scroll down, near the end) to get a PIL Image, and then use its save() method:

def store_temp_image(data, imagetk):
    # do sanity/validation checks here, if need be
    new_file_name = data.number + ".jpg"
    imgpil = ImageTk.getimage( imagetk )
    imgpil.save( os.path.join("/tmp/myapp", new_file_name), "JPEG" )
    imgpil.close()    # just in case (not sure if save() also closes imgpil)

Upvotes: 6

Nicolas Abril
Nicolas Abril

Reputation: 161

Looking at the source code for the ImageTk module, you can see that it actually creates a tkinter.PhotoImage object and stores it as __photo.

self.__photo = tkinter.PhotoImage(**kw)

this attribute is accessible as _PhotoImage__photo (because of the leading __, it's name has been mangled).
Then, to save your image, you can do:

image._PhotoImage__photo.write("/tmp/myapp"+new_file_name)

Be warned that this only supports a very limited choice of file formats. It worked for me with png files, gif files and ppm files, but not with jpg files.

Upvotes: 1

glenfant
glenfant

Reputation: 1318

Have a look at this...

http://pillow.readthedocs.io/en/3.1.x/reference/ImageTk.html#PIL.ImageTk.PhotoImage

From there you can get the included Image object. Which has a save(...) method that does the job you're expecting.

http://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.save

Thus this (untested) code should do the job :

def store_temp_image(data, image):
    new_file_name = data.number + ".jpg"
    new_file_path = os.path.join('/tmp/myapp', new_file_name)
    image.image.save(new_file_path)

Hope this helped!

Upvotes: 0

Related Questions