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.