0

I am trying to convert colour images into Grayscale images and then save the output. The code works fine as expected (I am able to import images and perfrom grayscale operations on it) However, I am unable to save the tk PhotoImage, hence, getting the error

'PhotoImage' object has no attribute 'save'

This is the code

from tkinter import *
from PIL import Image
from PIL import ImageTk
from tkinter import filedialog
import cv2

gray = None


def select_image():
    global left_side, right_side

    f_types = [
        ("Jpg Files", "*.jpg"),
        ("PNG Files", "*.png"),
    ]  # type of files to select
    path = filedialog.askopenfilename(multiple=False, filetypes=f_types)

    # ensure a file path was selected
    if len(path) > 0:

        image = cv2.imread(path)
        print(path)
        global gray
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

        # convert the images to PIL format...
        image = Image.fromarray(image)
        gray = Image.fromarray(gray)

        # ...and then to ImageTk format
        image = ImageTk.PhotoImage(image)
        gray = ImageTk.PhotoImage(gray)

        # if the sections are None, initialize them
        if left_side is None or right_side is None:
            # the first section will store our original image
            left_side = Label(image=image)
            left_side.image = image
            left_side.pack(side="left", padx=10, pady=10)

            # while the second section will store the edge map
            right_side = Label(image=gray)
            right_side.image = gray
            right_side.pack(side="right", padx=10, pady=10)

        # otherwise, update the image sections
        else:
            # update the sections
            left_side.configure(image=image)
            right_side.configure(image=gray)
            left_side.image = image
            right_side.image = gray


# save bw
def savefile():
    filename = filedialog.asksaveasfile(mode="w", defaultextension=".jpg")
    if not filename:
        return
    gray.save(filename)
    # print(gray)

window = Tk()
window.geometry("1080x720")
window.title("Colored Image To Black & White")

icon = PhotoImage(file="logo1.png")
window.iconphoto(True, icon)

image = PhotoImage(file="logo1.png")
intro = Label(
    window,
    text="This program converts Colored Images into Grayscale Images",
    font=("Comic Sans", 20,),
    fg="#FF6405",
    bg="black",
    compound="right",
)
intro.pack()

left_side = None
right_side = None

btn = Button(
    window,
    text="select image",
    command=select_image,
    font=("Comic Sans", 30),
    fg="red",
    bg="black",
)

btn1 = Button(
    window,
    text="select image",
    command=savefile,
    font=("Comic Sans", 30),
    fg="red",
    bg="black",
)

img = PhotoImage(file="select.png")
btn.config(image=img)
btn.pack(side="left", fill="both", expand="no", padx="10", pady="10")

img2 = PhotoImage(file="save.png")
btn1.config(image=img2)
btn1.pack(side="right", fill="both", expand="no", padx="10", pady="10")

window.config(background="#FF6405")
# window.resizable(False, False)
window.mainloop()
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
  • look at here https://stackoverflow.com/questions/25387745/how-can-i-save-tkinter-photoimage-to-gif – Сергей Кох Apr 23 '22 at 04:57
  • @Сергей I want to use filedialog.asksaveasfile to save the file... I don't think the that method would work for me. – thebigbrownBox Apr 23 '22 at 14:32
  • 1
    save function works with PIL.Image class and not with PhotoImage class. – Michael Stevens Oct 14, 2021 at 16:41 – Сергей Кох Apr 23 '22 at 17:03
  • 1
    A `PhotoImage` exists for the sole purpose of being displayed by a Tk widget; it has no need of a `.save()` method. The thing you want to save is the PIL `Image` that the `PhotoImage` was created from; currently you're overwriting that variable, you need to use two different names. – jasonharper Apr 23 '22 at 17:08

0 Answers0