James Huang
James Huang

Reputation: 876

PIL Python Module throwing error when saving image with Tkinter

Whenever I try to save an image selected from tkinter, I get an error like this:

    raise ValueError("unknown file extension: {}".format(ext)) from e
ValueError: unknown file extension: 

I'm using tkinter to open up the file browser to select an image file. The user can choose to flip the image horizontally and vertically. After that, they can choose to save as a variety of image formats. However, this returns the above error. I don't really see what is wrong. The name variable in the save() function contains the name after the file is picked. PIL's save function should be able to take that name and save it in the current working directory.

from tkinter import *
from tkinter import filedialog
from PIL import Image


def open_image():
    global img
    img = Image.open(
        filedialog.askopenfilename(title="Select file", filetypes=(("jpeg files", "*.jpg"), ("all files", "*.*"))))
    save_button.config(bg=default_color)
    flip_horizontal_button.config(bg=default_color)
    flip_vertical_button.config(bg=default_color)


def flip_horizontal():
    global img
    if img:
        img = img.transpose(Image.FLIP_LEFT_RIGHT)


def flip_vertical():
    global img
    if img:
        img = img.transpose(Image.FLIP_TOP_BOTTOM)


def save():
    global img
    if img:
        #os.chdir("/")
        default_name = "Untitled"
        """ print(default_name+"."+img.format)
        print(os.path.isfile(default_name+"."+img.format))
        print(os.path)
        if os.path.isfile(default_name+"."+img.format):
            expand = 1
            while True:
                expand += 1
                expanded_name = default_name+str(expand)
                if os.path.isfile(expanded_name):
                    continue
                else:
                    default_name = expanded_name
                    break"""
        name = filedialog.asksaveasfilename(title="Save As", filetypes=(
            ('JPEG', ('*.jpg', '*.jpeg', '*.jpe')), ('PNG', '*.png'), ('GIF', '*.gif')),
                                            initialfile=default_name+"."+img.format)
        img.save(name)


img = None

root = Tk()
root.title("Meme Deep Fryer")
root.geometry('600x500')
default_color = root.cget('bg')

open_button = Button(text='Open Image', font=('Arial', 20), command=open_image)
flip_horizontal_button = Button(text='Flip Horizontal', font=('Arial', 10), command=flip_horizontal, bg="gray")
flip_vertical_button = Button(text='Flip Vertical', font=('Arial', 10), command=flip_vertical, bg="gray")
save_button = Button(text='Save', font=('Arial', 20), command=save, bg="gray")

open_button.pack(anchor='nw', side=LEFT)
save_button.pack(anchor='nw', side=LEFT)
flip_horizontal_button.pack(anchor='w')
flip_vertical_button.pack(anchor='w')

root.mainloop()


Upvotes: 0

Views: 559

Answers (1)

jizhihaoSAMA
jizhihaoSAMA

Reputation: 12672

You could pass argument typevariable in asksaveasfilename:

ext = tkinter.StringVar()
name = filedialog.asksaveasfilename(title="Select file", typevariable=ext, filetypes=(('JPEG', ('*.jpg', '*.jpeg', '*.jpe')), ('PNG', '*.png'), ('BMP', ('*.bmp', '*.jdib')), ('GIF', '*.gif')))

if name: 
    img.save(os.path.basename(name)+"."+ext.get().lower()) # splice the string and the extension.

Upvotes: 2

Related Questions