使用ImageTk PhotoImage .paste()方法产生AttributeError

时间:2017-10-28 17:39:13

标签: python tkinter

我正在使用tkinter处理应用程序,该应用程序允许用户从图像中收集数据。现在,我试图允许用户在图像上画一条线来指定从哪里收集数据。似乎有很多方法可以用这种方式绘制一条线,但我尝试使用PhotoImage对象的.paste()方法。

以下是相关的代码部分:

import openpyxl, PIL.Image, sys, openpyxl, glob, numpy
from tkinter import *
from PIL import Image, ImageTk

class App(object):

    instructions = ['Draw line within ventral patch', 'Draw line within eye ring',
                    'Draw line from eye ring to face', 
                    'Draw proximal line from dorsal patch to ventral patch', 
                    'Draw medial line from dorsal patch to ventral patch',
                    'Draw distal line from dorsal patch to ventral patch'
                    ]

    NUMSTEPS = len(instructions)

    def __init__(self, root):

        self.root = root
        w, h = root.winfo_screenwidth() * .9, root.winfo_screenheight() * .9
        root.geometry("%dx%d+0+0" % (w, h))

        root.title('Squirrel Project')
        root.wm_iconbitmap('Squirrel.ico')

        instruction = Label(root, text = self.instructions[self.getStep()])
        instruction.pack(side = TOP)

        im = self.getImage()
        imageViewer = Label(root)
        imageViewer.pack(fill = BOTH, expand = True)
        root.update()
        imageViewerSize = [imageViewer.winfo_height(), imageViewer.winfo_width()]
        im = self.imageResize(im, imageViewerSize)

        self.im = ImageTk.PhotoImage(im)
        im = self.im

        imageViewer = Label(root, image = im, cursor = 'cross')
        root.update()
        imageViewer.image = im

        imageViewer.bind('<B1-Motion>', self.drawTempLine)

        imageViewer.pack()


        buttonFrame = Frame(root, width = w, height = 25, padx = 15, pady = 15, relief = 'raised')
        buttonFrame.pack(side = BOTTOM)

        saveButton = Button(buttonFrame, text = 'Confirm', command = self.save, padx = 30)
        saveButton.pack(side = LEFT, padx = 60)

        undoButton = Button(buttonFrame, text = 'Undo', command = self.undo, padx = 30)
        undoButton.pack(side = RIGHT, padx = 60)

        colorArray = numpy.array(([0], [0], [255]), dtype = int) 
        pixIm = Image.fromarray(colorArray)
        self.pixIm = ImageTk.PhotoImage(pixIm)

    def getImage(self):
        files = [file for file in glob.glob('C://Users/Alec/Desktop/Squirrels/Smithsonian/lateral/*.jpg')]

        counter = 0
        seen = []
        for x in range(1, self.sheet.max_row):
            Id = self.sheet.cell(row = x, colun = 1).value
            seen.append(Id)    

        for file in files:
            counter += 1
            if file not in seen:
                break

        im = file
        im = Image.open(im)

        return im

    def imageResize(self, image, constraint):
        actualSize = [image.height, image.width]

        if actualSize[0] > actualSize[1]:
            factor = constraint[0] / actualSize[0]
        else: 
            factor = constraint[1] / actualSize[1]

        newSize = [value * factor for value in actualSize]
        image.thumbnail(tuple(newSize))
        return image

    def getStep(self):
        return 0

    def drawTempLine(self, event):
        self.im.paste(self.pixIm, (event.x - 1, event.y - 1, event.x + 1, event.y + 1))


app = Tk()
App(app)

app.mainloop()

这会导致以下错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Alec\Anaconda3\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:/Users/Alec/Contrast App.py", line 146, in drawTempLine
    self.im.paste(self.pixIm, (event.x - 1, event.y - 1, event.x + 1, event.y + 1))
  File "C:\Users\Alec\Anaconda3\lib\site-packages\PIL\ImageTk.py", line 177, in paste
    im.load()
AttributeError: 'PhotoImage' object has no attribute 'load'

导致此属性错误的原因是什么?如何更正?

1 个答案:

答案 0 :(得分:0)

Image有粘贴方法,而不是PhotoImage

您需要修改图像,然后将其重新转换为PhotoImage以显示它。

除非您显示完整示例,否则我们无法使用您的代码,就像我们可以运行的那样。