Tkinter 画布图像错误

问题描述

我正在以 oop 风格重写我的应用程序,但遇到了一个意想不到的问题。调色板图像失真。这是以前从未发生过的。

enter image description here

类容器

class MainApp(Frame):
    def __init__(self,master,path):
        self.master = master
        Frame.__init__(self,self.master)

        self.configure_main()

        coloring = Coloring(self.master,path)
        coloring.grid(row=1,column=1)

从中实例化颜色选择器实例的类

class Coloring(Frame):  
    def __init__(self,parent,path):
        self.parent = parent
        Frame.__init__(self,self.parent)

        ...
        
        self.create_widgets()
        self.draw_widgets()
  
    def change_custom_color(self,*args):
        try:
            self.selector_frame.destroy()
        except AttributeError:
            pass

        self.selector_frame = ColorSelector(self.parent.master,args[1],self)
        self.selector_frame.grid(row=1,column=0)

颜色选择器类

class ColorSelector(Frame):
    def __init__(self,btn_idx,coloring_obj):
        self.parent = parent
        Frame.__init__(self,self.parent)

        self.btn_idx = btn_idx

        self.palette_img_np = cv2.imread('resources/palette.png')
        self.palette_img_tk = cv2pil_images(self.palette_img_np)

        self.coloring_obj = coloring_obj

        self.create_widgets()
        self.draw_widgets()

    def create_widgets(self):
        self.palette = Canvas(self,width=253,height=253)
        self.palette.create_image(128,3,anchor='n',image=self.palette_img_tk)
        self.palette.create_oval(5,251,outline='black',width=4)
        self.cursor_obj_id = self.palette.create_oval(81,81,71,fill='green',outline='white')
        self.palette.bind("<B1-Motion>",lambda event,arg=self.btn_idx: self.cursor_move(event,arg))

        self.slider_explanation = Label(self,text='Color saturation:')

        self.enchance_var = Intvar(value=1.0)
        self.enhance_slider = Scale(
            self,from_=0.1,to=1.0,orient=HORIZONTAL,command=lambda event,arg=self.btn_idx: self.change_enhance(event,arg),resolution=0.0001,variable=self.enchance_var,length=200
        )

        self.ok_btn = Button(self,text='OK',command=self.destroy)

    def draw_widgets(self):
        self.palette.pack(padx=15)
        self.slider_explanation.pack()
        self.enhance_slider.pack()
        self.ok_btn.pack(pady=10)

没有bug的截图

enter image description here

提前致谢。

解决方法

问题可能是数组转换什么的,建议使用PIL本身来加载和使用图片,这样更容易。作为一种解决方法,您可以使用 cv2.imwrite() 并保存图像,然后使用该路径并使用 PIL 打开新图像。类似的东西:

# All the other processes...
path = 'img1.png' 
cv2.imwrite(path)

img = PIL.ImageTk.PhotoImage(Image.open(file))

并使用 img 作为图像等等。

这可能是您的阵列的一些错误,因为它对我来说无法重现,它运行良好,无论如何这里有一个我会使用的函数:

def cv2pil(array):
    img = cv2.cvtColor(array,cv2.COLOR_BGR2RGB) # Also try COLOR_BGR2RGBA for png?
    pil_img = ImageTk.PhotoImage(Image.fromarray(img))
    return pil_img

img = cv2.imread('capture.png')
pil = cv2pil(img)

除了颜色模式切换之外,我没有看到任何其他失真。