By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,983 Members | 1,717 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,983 IT Pros & Developers. It's quick & easy.

Updating image with each iteration of a loop and displaying in window.

P: 1
I have a while loop that continues for the set amount of iterations and in each iteration a different image is generated. What I am trying to do is to create the image, display it in a window, and then repeat the loop over.

The problem I am having is I am using PIL to generate an image which you can see below:

def make_image(self, filename):
image = Image.new("RGB", (self.map_width, self.map_height))
pix = image.load()
rgb_min_factor, rgb_max_factor, = 0.875, 1.0
for x_value in range(self.map_width):
for y_value in range(self.map_height):
current_state = self.map[x_value][y_value].get_state()

pix[x_value, y_value] = \
(int(self.red_values[current_state] * random.uniform(rgb_min_factor, rgb_max_factor)), \
int(self.green_values[current_state] * random.uniform(rgb_min_factor, rgb_max_factor)), \
int(self.blue_values[current_state] * random.uniform(rgb_min_factor, rgb_max_factor)))

image.save(filename + ".png", "PNG")

print(filename + ".png has been generated and saved in the directory of the python file.")
I attempted adding a return statement and pass it through Tkinter, but numerous errors were being thrown, simply because I cannot find a write-up showing me resources for handling an issue such as this in Python 3 while using PIL at the same time.

Below is the method that I would utulize the newly generated image in: def run_iterations(self, num_loops): self.num_loops = num_loops self.loops_made = 0

while self.loops_made < self.num_loops:
if self.loops_made == 0:
self.make_image("Map_Initial_" + str(self.loops_made + 1))

self.update_map_state()

if self.loops_made == self.num_loops - 1:
self.make_image("Map_Final_" + str(self.loops_made + 1))

print("Iteration:", self.loops_made + 1, "(", "{:.2f}".format(time.time() - self.start_time), ")")

self.loops_made += 1
I am currently using the import:

from PIL import Image, ImageTk
import tkinter as tk
I just want a basic GUI just displaying the image and updating with every iteration of the loop, any help is greatly appreciated.

I have even attempted to create the below class in order to create the window and use the image that I am generating:

class Window:
def create_window(self, image):
root = tk.Tk()
canvas = tk.Canvas(root, width = 500, height = 500)
canvas.pack()

img = Image.open(image)
tk_img = ImageTk.PhotoImage(img)
canvas.create_image(250, 250, image = tk_img)
root.mainloop()
and change the line: self.make_image("Map_Initial_" + str(self.loops_made + 1))to self.window.create_window(self.make_image("Map_Ini tial_" + str(self.loops_made + 1))), but that gives me the error: prefix = fp.read(16)
AttributeError: 'Image' object has no attribute 'read'

I have exhausted all the options I can find, I have done all the hard stuff I think, it seems to be something simple holding me back, but I am not too sure honestly.

EDIT:

My window class has been updated to:

class Window:

def create_window(self, image_to_load):
root = tk.Tk()
root.title("Cellular Automata Map Generation")

image = ImageTk.PhotoImage(Image.open(image_to_load))

x = (root.winfo_screenwidth() / 2) - (image.width() / 2)
y = (root.winfo_screenheight() / 2) - (image.height() / 2)

root.geometry('%dx%d+%d+%d' % (image.width(), image.height(), x, y))
root.resizable(0,0)

canvas = tk.Canvas(root, width = image.width() + 10, height = image.height() + 10)
canvas.pack()

imagesprite = canvas.create_image(image.width() / 2, image.height() / 2, image = image)
root.mainloop()
and in my run_iterations() method I changed the generation of the image to:

self.window.create_window(self.make_image("Map_Ini tial_" + str(self.loops_made + 1)))
What this does now is that the image is generated correctly and the first iteration of the loop opens the window, though I cannot find a way to update the image with every iteration of the loop.
Dec 1 '16 #1
Share this Question
Share on Google+
1 Reply


Expert 100+
P: 619
The problem is most likely the while(). It is always running and does not allow the program any time to update the canvas. You can try update or update_idletasks, but the preferred way is to use after() and allow some time for the program to update. My rule of thumb is at least 1/10 of a second. The following program uses a one second interval so your eyes can see the changes.
Expand|Select|Wrap|Line Numbers
  1. import sys
  2. if sys.version_info[0] < 3:
  3.     import Tkinter as tk     ## Python 2.x
  4. else:
  5.     import tkinter as tk     ## Python 3.x
  6.  
  7. class Window:
  8.     def __init__(self):
  9.         self.photos=[]
  10.         self.img=""
  11.         self.loops_made=0
  12.         root = tk.Tk()
  13.         self.canvas = tk.Canvas(root, width = 500, height = 500)
  14.         self.canvas.grid()
  15.         self.load_images()
  16.         self.next_image()
  17.  
  18.         tk.Button(root, text="Quit", bg="orange",
  19.                   command=root.quit).grid(row=1)
  20.  
  21.         root.mainloop()
  22.  
  23.     def next_image(self):
  24.         if self.loops_made < 3:  ## there are only 3 images
  25.             self.canvas.delete(self.img)  ## delete previous image
  26.             self.img=self.canvas.create_image(250, 250,
  27.                                      image=self.photos[self.loops_made])
  28.             self.canvas.after(1000, self.next_image)  ## 1 second
  29.         self.loops_made += 1
  30.  
  31.     def load_images(self):
  32.         """ some common images to use for testing
  33.             copy data images to a list that is an instance variable
  34.         """
  35.         ladybug_gif_b64='''\
  36. R0lGODlhIAAgALMAAP///wAAADAwMP99Hf8AAP+lAP//AMopUwAAAAAAAAAAAAAAAAAAAAAAAAAA
  37. AAAAACH5BAAAAAAALAAAAAAgACAAAwTHEMhJq714hp3lDh0GiqH2UWOVAt96pUIsBLKglWg87Dwv
  38. 4xMBj0Asxgg+XKxwLBJrxUGsI5TKnARoVHoLDp5XbNP5cwmNAqwa/aOc13ByrfKOw2UGw1SSxrb+
  39. AWIxeXsAaX92UDQ1Nh6BdneMhQIHkHGSjYaVlmt4epmacp19YAKEoJRspKWrjBapWWGqcm1uB5tj
  40. ok4HZa+3m5wEt5kuhpTAcb+FVL/NzspAfDHPysslMJjEIS0oLygnOMVd0SwcHeDk6errEQA7
  41. '''
  42.  
  43.         grape_gif='''\
  44. R0lGODlhIAAgALMAAAAAAAAAgHCAkC6LV76+vvXeswD/ANzc3DLNMubm+v/6zS9PT6Ai8P8A////
  45. /////yH5BAEAAAkALAAAAAAgACAAAAS00MlJq7046803AF3ofAYYfh8GIEvpoUZcmtOKAO5rLMva
  46. 0rYVKqX5IEq3XDAZo1GGiOhw5rtJc09cVGo7orYwYtYo3d4+DBxJWuSCAQ30+vNTGcxnOIARj3eT
  47. YhJDQ3woDGl7foNiKBV7aYeEkHEignKFkk4ciYaImJqbkZ+PjZUjaJOElKanqJyRrJyZgSKkokOs
  48. NYa2q7mcirC5I5FofsK6hcHHgsSgx4a9yzXK0rrV19gRADs=
  49. '''
  50.  
  51.         house='''R0lGODdhFQAVAPMAAAQ2PESapISCBASCBMTCxPxmNCQiJJya/ISChGRmzPz+/PxmzDQyZDQyZDQy
  52. ZDQyZCwAAAAAFQAVAAAElJDISau9Vh2WMD0gqHHelJwnsXVloqDd2hrMm8pYYiSHYfMMRm53ULlQ
  53. HGFFx1MZCciUiVOsPmEkKNVp3UBhJ4Ohy1UxerSgJGZMMBbcBACQlVhRiHvaUsXHgywTdycLdxyB
  54. gm1vcTyIZW4MeU6NgQEBXEGRcQcIlwQIAwEHoioCAgWmCZ0Iq5+hA6wIpqislgGhthEAOw==
  55. '''
  56.  
  57.         for photo in (ladybug_gif_b64, grape_gif, house):
  58.            self.photos.append(tk.PhotoImage(data=photo))
  59.  
  60. W=Window() 
Dec 1 '16 #2

Post your reply

Sign in to post your reply or Sign up for a free account.