Hale
Hale

Reputation: 163

How to change background color in quicker way?

I am doing a painting program where one can draw things, change the background color and save it as a file on the computer. Everything works except that changing the background color takes way too much time.

This is the code:

from tkinter import *
import tkinter.filedialog as tk
from tkinter import Menu
from tkinter.colorchooser import askcolor
from tkinter.filedialog import asksaveasfile,askopenfilename
import os
from PIL import Image as im
from PIL import ImageTk,ImageDraw,ImageColor


class P:
    x=y=None
    image=None

    my_image=im.new("RGB",(600,600),(255,255,255))
    draw=ImageDraw.Draw(my_image)
    
    def __init__(self,window):
        self.window = window
        self.upper_frame = Frame(window)
        self.upper_frame.grid(row=0,column=0, padx=10, pady=5,sticky="ew")
        self.lower_frame = Frame(window)
        self.lower_frame.grid(row=2, column=0, padx=10, pady=5,sticky="ew")
        self.canvas= Canvas(self.lower_frame,width=700,height=530,bg="white")
        self.canvas.grid()
        self.bg = Button(self.upper_frame,text="Background",command= self.bgcolor) #change bg color
        self.bg.grid(row=2,column=1,padx=(100,10))
        self.upper_menu()

    def bgcolor(self):
            chosen_color = askcolor(color=self.canvas["bg"])[1]
            self.canvas.configure(bg=chosen_color)
            color_RGB = ImageColor.getcolor(chosen_color, "RGB")
            img = self.my_image
            for i in range(0,600):#pixels in width
                for j in range(0,600): #height = 600 pix
                    data = img.getpixel((i,j)) #gives color of pixel
                    if (data[0]==255 and data[1]==255 and data[2]==255): #data represent RGB color
                        img.putpixel((i,j),color_RGB) #changes pixel color
    
    def save_pic(self,event=None): #save image on comp.
        my_file=asksaveasfile(mode="w",defaultextension=".png",filetypes=[("png files","*.png")],
                              initialdir="/home/b/",parent=window)
        
        if my_file is not None:
            path=os.path.abspath(my_file.name)
            self.my_image.save(path)
            
    def upper_menu(self):
        self.menubar = Menu(window)
        self.menu1 = Menu(self.menubar, tearoff=0)
        self.menu1.add_command(label="Save pic", command=self.save_pic)
        self.menu1.add_separator()
        self.menu1.add_command(label="Exit", command=window.destroy)
        self.menubar.add_cascade(label="Settings", menu=self.menu1)
        self.menu2 = Menu(self.menubar, tearoff=0)
        self.window.config(menu=self.menubar)
            
window = Tk()
window.geometry("720x590")
p = P(window)

window.mainloop()

I use the method bgcolor to change the background. How to make it work faster?

Upvotes: 0

Views: 70

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386210

I suspect the problem is with calling putpixel 360,000 times. Instead, try creating the color data in the loop and then call putdata once after the loops have finished.

I'm not overly familiar with PIL, but this makes a huge difference when doing similar things with the tkinter PhotoImage class: doing one pixel at a time is slow, doing an array of pixels is fast.

Upvotes: 1

Related Questions