1

I have a program for image treatment. The program itself works fine, but when I change the desktop or laptop (all on windows 7) I'm using it in, it sometimes says randomly:

Traceback (most recent call last):
  File "P:\ISN\Projets\Traitement image\Test 2.py", line 152, in <module>
    im1 = Tkinter.PhotoImage(file=a)
  File "C:\Program Files\EduPython\App\lib\tkinter\__init__.py", line 3287, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "C:\Program Files\EduPython\App\lib\tkinter\__init__.py", line 3243, in __init__
    self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't recognize data in image file "P:/ISN/Projets/Traitement image/Images/obama.png"

As you can see, the image format is .png. I'm using PIL, so png images are supposed to be supported, and my image files are not corrupted. I use them all the time, and they work fine. But this randomly happens, and I'm afraid the day I'll have to present my program, it would crash on me. Here's my code:

from tkinter import*
import tkinter as Tkinter
from tkinter import filedialog, DISABLED, messagebox as tkMessageBox
import os
import ntpath
from PIL import Image
from collections import Counter


def EchelleDeGris():
    Ima2=Image.new("RGB",(z[0],z[1]))
    px=Ima1.load()
    px1=Ima2.load()
    for x in range(z[0]):
        for y in range(z[1]):
            p=px[x,y]
            o=int((p[0]+p[1]+p[2])/3)
            px1[x,y]=(o,o,o)
    Ima2.save("ImageMod.png")
    im2 = PhotoImage(file="ImageMod.png")
    main.image = im2
    I2 = Tkinter.Label(main, image=im2)
    I2.grid(row=0, column=3, rowspan =6)

def SupprimerImage():
    I2 = Tkinter.Label(main, image=imt)
    I2.grid(row=0, column=3, rowspan =6)

def Luminosite():
    Ima2=Image.new("RGB",(z[0],z[1]))
    px=Ima1.load()
    px1=Ima2.load()
    for x in range(z[0]):
        for y in range(z[1]):
            p=px[x,y]
            px1[x,y]=(p[0]+S1.get(),p[1]+S1.get(),p[2]+S1.get())
    Ima2.save("ImageMod.png")
    im2 = PhotoImage(file="ImageMod.png")
    main.image = im2
    I2 = Tkinter.Label(main, image=im2)
    I2.grid(row=0, column=3, rowspan =6)

def AnnulerModifications():
    I2 = Tkinter.Label(main, image=im1)
    I2.grid(row=0, column=3, rowspan =6)

def get_pixel(pixels, x, y):
    try:
        return pixels[x, y]
    except IndexError:
        return None


def get_neighbors(pixels, x, y):
    neighbors = list()
    neighbors.append(get_pixel(pixels, x, y - 1))
    neighbors.append(get_pixel(pixels, x, y + 1))
    neighbors.append(get_pixel(pixels, x - 1, y))
    neighbors.append(get_pixel(pixels, x + 1, y))
    neighbors.append(get_pixel(pixels, x - 1, y - 1))
    neighbors.append(get_pixel(pixels, x - 1, y + 1))
    neighbors.append(get_pixel(pixels, x + 1, y - 1))
    neighbors.append(get_pixel(pixels, x + 1, y + 1))
    return neighbors


def filter_art(pixels, size):
    indexes = dict()
    for x in range(size[0]):
        for y in range(size[1]):
            color = get_pixel(pixels, x, y)
            neighbors = get_neighbors(pixels, x, y)
            new_color = Counter(neighbors).most_common()[0][0]
            if new_color is not None:
                indexes[x, y] = new_color
    for x, y in indexes:
        pixels[x, y] = indexes[x, y]


def pop_art(path_orig, path_mod, coef):  # coef is integer value, meant how deep filtering would be (for example, coef=4)
    image_orig = Image.open(path_orig)
    size = image_orig.size
    image_mod = Image.new("RGB",(size[0],size[1]))
    pixels_orig = image_orig.load()
    pixels_mod = image_mod.load()
    for x in range(size[0]):
        for y in range(size[1]):
            p = pixels_orig[x, y]
            if isinstance(p, int): # this should be done using PIL palletes and converting to exact pallete at first,
                # but now I omit this for my quick test
                rgb = (p,p,p)
            elif isinstance(p, tuple) and len(p) in (3, 4):
                rgb = p[:3]
            else:
                raise TypeError('Unknown pallete')
            average_color = sum(rgb) / 3
            if average_color <= 85:
                pixels_mod[x, y] = (255, 0, 0)  # you also need care about guarantee correct PIL pallete format here (omitted)
            elif 85 < average_color <= 170:
                pixels_mod[x, y] = (0, 255, 0)
            elif average_color > 170:
                pixels_mod[x, y] = (0, 0, 255)
    for _ in range(coef):
        filter_art(pixels_mod, size)
    image_mod.save(path_mod)

def usepop():
    pop_art(a, 'result.png', coef=4)
    im2 = PhotoImage(file="result.png")
    main.image = im2
    I2 = Tkinter.Label(main, image=im2)
    I2.grid(row=0, column=3, rowspan =6)






main=Tk()

main.withdraw()
currdir = os.getcwd()
a = filedialog.askopenfilename()
main.deiconify()

main.configure(background="#a1dbcd")
main.title("Photoshop Version.Megzari")

Ima1=Image.open(a)
z=Ima1.size
nux=Image.new("RGB",(z[0],z[1]))
nuxy=nux.load()
for x in range(z[0]):
    for y in range(z[1]):
        nuxy[x,y]=(255,255,255)
nux.save("Blank.png")








if z>(400,400):
    main.withdraw()
    tkMessageBox.showinfo( "Resolution Error", "The image is too big, please select a smaller one.")
    sys.exit()


elif z<(400,400):
    im1 = Tkinter.PhotoImage(file=a)
    I1 = Tkinter.Label(main, image=im1)
    I1.grid(padx=20, pady=20, row=0, column=1, rowspan =6)
    imt = Tkinter.PhotoImage(file="Blank.png")
    T1 = Tkinter.Label(main, image=imt)
    T1.grid(padx=20, pady=20, row=0, column=3, rowspan =6)
    B1 = Tkinter.Button(main, text ="Echelle de gris", command = EchelleDeGris, fg="#a1dbcd", bg="#383a39", state=NORMAL)
    B1.grid(padx=20, pady=20, row=0, column=2)
    B3 = Tkinter.Button(main, text ="Appliquer Luminosité", command = Luminosite, fg="#a1dbcd", bg="#383a39")
    B3.grid(padx=20, pady=20, row=2, column=2)
    S1 = Scale(main, from_=0, to=254, orient=HORIZONTAL, fg="#a1dbcd", bg="#383a39", length = 200)
    S1.grid(row=1, column=2)
    B2 = Tkinter.Button(main, text ="Supprimer Image", command = SupprimerImage, fg="#a1dbcd", bg="#383a39")
    B2.grid(padx=20, pady=20, row=4, column=2)
    B3 = Tkinter.Button(main, text ="Annuler Modifications", command = AnnulerModifications, fg="#a1dbcd", bg="#383a39")
    B3.grid(padx=20, pady=20, row=3, column=2)
    B4 = Tkinter.Button(main, text ="Pop Art", command = usepop, fg="#a1dbcd", bg="#383a39")
    B4.grid(padx=20, pady=20, row=5, column=2)

    s=S1.get()




main.mainloop()
Megzari Nassim
  • 399
  • 2
  • 5
  • 24
  • you use standard `PhotoImage` from `tkinter` module which doesn't support `png`. You have to use `ImageTk.PhotoImage` from module `PIL` – furas Feb 03 '17 at 09:28
  • But I don't understand if it doesn't support why does it work and sometimes it doesn't ? I'll use this fix but I want to understand why it does that ? – Megzari Nassim Feb 03 '17 at 09:34
  • you had to check images - maybe you have GIF with extension .png or maybe newer tkinter works with some png but not with all types. – furas Feb 03 '17 at 09:43

1 Answers1

3

You use Tkinter.PhotoImage which doesn't support png.
You have to ude ImageTk.PhotoImage from module PIL

from PIL import Image, ImageTk


img2 = ImageTk.PhotoImage(...)

effbot.org: The Tkinter PhotoImage Class


EDIT 2021:

In 2020 documentation on effbot.org was removed but its copy is still avaliable on archive.org in links effbot.org and The Tkinter PhotoImage Class

Thanks for @GiovanniG.PY

furas
  • 134,197
  • 12
  • 106
  • 148
  • for effbot.org go here https://web.archive.org/web/20200315142708/http://effbot.org/ – PythonProgrammi Jan 26 '21 at 05:49
  • 1
    @GiovanniG.PY this answer is 3 years old. And effbot was removed last year :) But thanks for information - I can't check all my old answers to make this correction. – furas Jan 26 '21 at 12:05
  • I thought it could be helpful. as effbot was my fav site for tkinter documentation – PythonProgrammi Jan 27 '21 at 17:19
  • @GiovanniG.PY I like effbot too - even if some information are not complete - and I put link to effbot in many my answers. Few month ago I find out that they removed documentation but I can't find all links in my answers and change them. So your information was useful. If you find other links to effbot then also add comment that documentation was removed and now it available only in archive.org. – furas Jan 27 '21 at 18:08
  • Of course I wii, I have a link on my blog home page too just for it – PythonProgrammi Jan 27 '21 at 20:51