【问题标题】:python PIL and tkinter; brightening image and displaying itpython PIL 和 tkinter;增亮图像并显示它
【发布时间】:2012-11-10 16:57:30
【问题描述】:

我想要做的是打开一个带有两张图片的窗口(一张是另一张的精确副本)。然后,当我单击一个按钮时,它会更改右侧的图像。我希望这是有道理的。我没有的代码是:

from __future__ import division
from Tkinter import *
from PIL import Image, ImageTk, ImageFilter
import random

class MyApp(object):
    def __init__(self):
        self.root = Tk()
        self.root.wm_title("Image examples")

        img = Image.open("lineage.jpg").convert("RGB")
        (w, h) = (img.size[0], img.size[1])
        print (w, h)

        tkpi = ImageTk.PhotoImage(img)
        label = Label(self.root, image=tkpi)
        label.grid(row=0, column=0, padx=5, pady=5, rowspan=10)

        img2 = img.copy()
        pixels = img2.load()

        tkpi2 = ImageTk.PhotoImage(img2)
        label = Label(self.root, image=tkpi2)
        label.grid(row=0, column=1, padx=5, pady=5, rowspan=10)

        Button(self.root, text="Brighten", command=self.brighten).grid(row=0, column= 2)  
        self.root.mainloop()

    def brighten(self):
        self.pixels = self.pixels.point(lambda x: x*1.9)          
MyApp()

当我点击brighten 按钮时,我想要更新img2。当我现在尝试时,我得到了这个错误:

File "C:\Users\Admin\Desktop\imageeditor.py", line 36, in brighten
self.pixels = self.pixels.point(lambda x: x*1.9)
AttributeError: 'MyApp' object has no attribute 'pixels'

正如您所说,我是编程新手,所以任何能帮助我走上正轨的帮助都会很棒。

【问题讨论】:

    标签: python python-2.7 tkinter python-imaging-library


    【解决方案1】:

    下面是一个完整的解决方案。以下是一些关于所做更改的 cmets:

    • 以前__init__ 方法从未返回,因为它最后调用了self.root.mainloop()。这可能会导致一些问题。我对其进行了重组,使其更像 python 文档中的 hello world 示例。
    • 有一个很棒的 Darken/Lighten Example,这就是 brighten() 方法的模型。
    • 有一个from Tkinter import *,它被from Tkinter import Frame, Tk, Label, Button 取代。事实证明,PIL 和 Tkinter 都有一个名为 Image 的属性,使用起来真的很混乱。尽量避免使用from module import *,而是明确说明您要导入的内容,这将防止名称空间冲突。

    代码

    from Tkinter import Frame, Tk, Label, Button
    from PIL import Image, ImageTk, ImageFilter
    
    class Application(Frame):
        def __init__(self, master=None):
            Frame.__init__(self, master)
            master.wm_title("Image examples")
            self.pack()
            self.createWidgets()
    
        def createWidgets(self):
            self.img = Image.open("lineage.jpg")
            self.photo1 = ImageTk.PhotoImage(self.img.convert("RGB"))
            self.label1 = Label(self, image=self.photo1)
            self.label1.grid(row=0, column=0)
    
            self.photo2 = ImageTk.PhotoImage(self.img.convert("RGB"))
            self.label2 = Label(self, image=self.photo2)
            self.label2.grid(row=0, column=1)
    
            button = Button(self, text="Brighten", command=self.brighten)
            button.grid(row=0, column=2)
    
        def brighten(self):
            img2 = self.img.point(lambda p: p * 1.9)
            self.photo2 = ImageTk.PhotoImage(img2)
            self.label2 = Label(self, image=self.photo2)
            self.label2.grid(row=0, column=1)
    
    root = Tk()
    app = Application(master=root)
    app.mainloop()
    root.destroy()
    

    【讨论】:

    • 似乎解决了这个错误,但给了我这个'文件“C:\Users\Admin\Desktop\imageeditor.py”,第 32 行,照亮 self.pixels = self.pixels.point( lambda x: x*1.9) AttributeError: 'PixelAccess' 对象没有属性 'point''
    • 是的,我试过了,得到了同样的错误。我现在正在处理它
    • 感谢您的尝试,如果您想出解决方案,请告诉我。
    • 谢谢!你的代码比我的更干净、更容易理解。
    【解决方案2】:

    我有一个工作的。

    from __future__ import division
    from Tkinter import *
    from PIL import Image, ImageTk, ImageFilter
    import random
    
    class MyApp(object):
        def __init__(self):
            self.root = Tk()
            self.root.wm_title("Image examples")
    
            img = Image.open("lineage.jpg").convert("RGB")
            (self.w, self.h) = (img.size[0], img.size[1])
    
            self.tkpi = ImageTk.PhotoImage(img)
            self.label = Label(self.root, image=self.tkpi)
            self.label.grid(row=0, column=0, padx=5, pady=5, rowspan=10)
    
            self.img2 = img.copy()
            self.pixels = self.img2.load()
            self.width, self.height = self.img2.size
    
    
    
            self.tkpi2 = ImageTk.PhotoImage(self.img2)
            self.label2 = Label(self.root, image=self.tkpi2)
            self.label2.grid(row=0, column=1, padx=5, pady=5, rowspan=10)
    
            self.btn = Button(self.root, text="Brighten")
            self.btn.grid(row=0, column= 2)
            self.btn.bind('<Button-1>', self.brighten)
            self.root.mainloop()
    
        def brighten(self,*args):
    #        self.pixels = self.pixels.point(lambda x: x*1.9)
            for i in range(self.w):    # for every pixel:
                for j in range(self.h):
    #                print self.pixels[i,j]
                    self.pixels[i,j] = (int(self.pixels[i,j][0] * 1.9),
                                        int(self.pixels[i,j][1] * 1.9),
                                        int(self.pixels[i,j][2] * 1.9))
            self.tkpi2 = ImageTk.PhotoImage(self.img2)
            self.label2.configure(image = self.tkpi2)
            self.root.update_idletasks()
    MyApp()
    

    【讨论】: