2

I am using PIL in python 3 in a program that recolours an image. What it does is, it permanently loops through the pixel values of file.gif (which are returned as integers) and then adds 10 to each of them. I then want it to save the file, which can then be reopened to write to a tkinter label (I've got the rest, but I just need to know about the saving).

Using this code, I have got the program to open the image and display it in the window, then modify the pixel values, but it doesn't change the image displayed.

from tkinter import *
from PIL import Image
from PIL import Image, ImageTk
import time, sys

def col():
    global count1,count,pix,x,root
    count1+=1
    print("("+str(count1)+")")
    count=-1
    for i in pix:
        count+=1
        #print(i)
        i+=10
        pix[count]=i

    photo = PhotoImage(file="AI.gif")
    x.configure(image=photo)
    root.update()
    root.after(100, col)

root=Tk()

photo = PhotoImage(file="AI.gif")
x=Label(root, compound="top", image=photo)
x.pack(side="right")

img = Image.open("AI.gif")
pix=list(img.getdata())
width=img.size[0]
height=img.size[1]
img.close()

root.geometry((str(width)+"x"+str(height))+"-0+0")
root.update()

count1=0
col()

root.mainloop()

I am using this image currently: enter image description here

Edit: @Tadhg McDonald-Jensen I've just run the program with all your suggested edits, but have got this error:

Traceback (most recent call last):
  File "C:\Users\name\Desktop\recolour1.py", line 47, in <module>
    col()
  File "C:\Users\name\Desktop\recolour1.py", line 19, in col
    photo.paste(img)
AttributeError: 'PhotoImage' object has no attribute 'paste'

Edit2: here is my latest version of the code that doesn't seem to be modifying the image in the tkinter window:

from tkinter import *
from PIL import Image
from PIL import Image, ImageTk
import time, sys

def col():
    global count1,count,pix,x,root,photo
    img = Image.open("AI.gif").convert("RGB")
    pix=list(img.getdata())
    count1+=1
    print("("+str(count1)+")")
    count=-1
    for i in pix:
        count+=1
        #print(i)
        i = tuple(V+100 for V in i)

    img.putdata(pix)
    photo.paste(img)
    root.update()
    img.close()
    root.after(10, col)

root=Tk()
photo = ImageTk.PhotoImage(file="AI.gif")
x=Label(root, compound="top", image=photo)
x.pack(side="right")
img = Image.open("AI.gif").convert("RGB")
width,height=img.size[0],img.size[1]
img.close()
root.geometry((str(width)+"x"+str(height))+"-0+0")
root.update()
count1=0
col()
root.mainloop()
7
  • why aren't you using ImageTk.PhotoImage? Commented Mar 25, 2016 at 21:58
  • How would I do that? I forgot to mention that I am still relatively new to tkinter Commented Mar 25, 2016 at 22:00
  • you never have to label yourself as new (your rep does help imply it) I'll happily post an answer... Commented Mar 25, 2016 at 22:07
  • you need to use ImageTk.PhotoImage, replace the line photo = PhotoImage("AI.gif") with photo = ImageTk.PhotoImage("AI.gif") Commented Mar 25, 2016 at 22:49
  • @Tadhg McDonald-Jensen I've tried all your suggestions and edits, but now it seems not to be updating the image again, it's doing everything else I want it to, just not that. I've posted the latest code above. Commented Mar 25, 2016 at 23:04

1 Answer 1

2

every time you do:

PhotoImage(file="AI.gif")

you are loading the file again, note that the file never changes throughout this process hence the image never changes. if you have loaded the image with PIL then you can use ImageTk.PhotoImage to load the data from the image:

photo = ImageTk.PhotoImage(img)

(be sure to do this after defining img) then you never need to re-open the image with this:

photo = PhotoImage(file="AI.gif")
x.configure(image=photo)

Instead you just need to put the new pixel data into img, then update photo with the new data in img with:

img.putdata(pix)
photo.paste(img)

EDIT: just to clarify here is your code with all my suggested edits:

from tkinter import *
from PIL import Image
from PIL import Image, ImageTk
import time, sys


def col():
    global count1,count,pix,x,root,img
    count1+=1
    print("("+str(count1)+")")
    count=-1
    for i in pix:
        count+=1
        #print(i)
        i+=10
        pix[count]=i

    #update the data in img and then paste it into photo
    img.putdata(pix)
    photo.paste(img)
    root.update()
    root.after(100, col)

root=Tk()

#load the image before making PhotoImage
img = Image.open("AI.gif")
pix=list(img.getdata())
width=img.size[0]
height=img.size[1]
#img.close() #don't close the image as you won't be able to modify it after closing

# do this part after defining img
photo = ImageTk.PhotoImage(img)
        # ^ use PIL's PhotoImage to use PIL operations on it
x=Label(root, compound="top", image=photo)
x.pack(side="right")

root.geometry((str(width)+"x"+str(height))+"-0+0")
root.update()

count1=0
col()

root.mainloop()
Sign up to request clarification or add additional context in comments.

7 Comments

I'd also like to mention that because the image is a gif increasing the pixel value by 10 is very likely not what you had in mind, you might need to convert it to RGB and modify that data instead.
How would I do that? I know it does it automatically for .jpg files, but I didn't realise you could do it for gifs as well
img = Image.open("AI.gif").convert("RGB")
then instead of just doing i+=10 you could do i = tuple(V +10 for V in i) to add 10 to each Red, Green and Blue value
Thanks, I've just been using a previous version of this program (that didn't work) designed to run with a gif, and wrote a really long program to modify the tuple, this should really help!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.