如何让我的程序在嵌套循环中更新此tkinter标签,以便显示灰度过程?

时间:2013-11-30 21:30:21

标签: python-3.x tkinter python-imaging-library

所以我制作了一个将图像转换为灰度的程序。我首先使用了Zelle的Python编程计算机科学入门书中的graphics.py.我相信这是基于tkinter。我使用嵌套循环完成程序迭代.gif图片并抓住每个单独的像素,用灰度算法替换它。我在循环中发生了变化,它给了它一个效果,显示整个窗口发生的灰度。这很慢,但看起来很整洁,但我意识到我希望能够使用更多的文件类型。我找到了Python 3.3和tkinter的PIL,使用PIL打开图像,将它们变成tkinter PhotoImage,而不是在tkinter窗口中显示它们。现在我的程序将在处理之前和之后显示图像,我只想看到程序更新循环中的图像,以便显示灰度处理。任何帮助都将非常感激。

这是我的代码:

from PIL import Image, ImageTk
from graphics import GraphWin
import tkinter

window = tkinter.Tk()
window.title('# Grayscale')

def GrayScaleConvertor():

    #Opens image, creates window and draws image
    picToConvert = 'sea.jpg'
    pic = Image.open(picToConvert)

    picWidth, picHeight = pic.size


    # Treats the image as a 2d array, iterates through changing the
    #values of each pixel with the algorithm for gray
    tkPic = ImageTk.PhotoImage(pic, master = window)
    label1 = tkinter.Label(window, image = tkPic)

    rgbList = pic.load() #Get a 2d array of the pixels
    for row in range(picWidth):
        for column in range(picHeight):
            rgb = rgbList[row,column]
            r,g,b = rgb # Unpacks the RGB value tuple per pixel
            grayAlgorithm1 = (r+g+b) // 3
            rgbList[row,column] = (grayAlgorithm1, grayAlgorithm1, grayAlgorithm1)

        # Converting to a tkinter PhotoImage
    tkPic1 = ImageTk.PhotoImage(pic, master = window)
    label2 = tkinter.Label(window, image = tkPic1)

    # Draws the images to the window
    label1.pack() # The image before grayscale
    label2.pack() # The image after being grayscaled
    window.mainloop()

GrayScaleConvertor()

1 个答案:

答案 0 :(得分:1)

您可以使用after(time, function_name)每10ms调用一次函数(例如)并更改一个(或更多)像素。

伪代码:

tkinter.after(10, change_one_pixel)

def change_one_pixel():
     change_next_pixel() # if you change more pixels you get faster animation
     create_new_image()
     update_label()
     if any_pixel_left:
        tkinter.after(10, change_one_pixel)

修改

完整的工作代码

#import Tkinter as tk # Python 2.7.x
import tkinter as tk # Python 3.x

from PIL import Image, ImageTk

class GrayScaleConvertor():

    def __init__(self):

        self.window = tk.Tk()
        self.window.title('# Grayscale')

        #Opens image, creates window and draws image
        picToConvert = 'sea.jpg'
        #picToConvert = 'background.jpg'
        self.pic = Image.open(picToConvert)

        # Treats the image as a 2d array, iterates through changing the
        #values of each pixel with the algorithm for gray
        self.tkPic1 = ImageTk.PhotoImage(self.pic, master = self.window)
        self.label1 = tk.Label(self.window, image = self.tkPic1)

        # Converting to a tkinter PhotoImage
        self.tkPic2 = ImageTk.PhotoImage(self.pic, master = self.window)
        self.label2 = tk.Label(self.window, image = self.tkPic2)

        # Draws the images to the window
        self.label1.pack() # The image before grayscale
        self.label2.pack() # The image after being grayscaled

        self.column = 0 # start column
        self.step = 10 # number columns in one step
        self.window.after(1, self.change_pixel) # 1ms

    def run(self):
        self.window.mainloop()

    def change_pixel(self):

        rgbList = self.pic.load() #Get a 2d array of the pixels
        picWidth, picHeight = self.pic.size

        # not to leave image
        if self.column + self.step > picWidth:
            self.step = picWidth - self.column

        # change columns
        for column in range(self.column, self.column+self.step):
            for row in range(picHeight):
                rgb = rgbList[column,row]
                r,g,b = rgb # Unpacks the RGB value tuple per pixel
                grayAlgorithm1 = (r+g+b) // 3
                rgbList[column,row] = (grayAlgorithm1, grayAlgorithm1, grayAlgorithm1)

        # change image in label
        if self.tkPic2:
            del self.tkPic2
        self.tkPic2 = ImageTk.PhotoImage(self.pic, master = self.window)
        self.label2.config(image = self.tkPic2)

        # move start column
        self.column += self.step

        # if still are columns - call again
        if self.column < picWidth:
            print "change image"
            self.window.after(1, self.change_pixel)
        else:
            print "the end"

GrayScaleConvertor().run()