Tkinter canvas 图像错误
Tkinter canvas image bug
我正在用 oop 风格重写我的应用程序,运行 遇到了一个意想不到的问题。调色板图像失真。这以前从未发生过。
class 容器
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
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
class ColorSelector(Frame):
def __init__(self, parent, 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, 3, 251, 251, outline='black', width=4)
self.cursor_obj_id = self.palette.create_oval(81, 81, 71, 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
提前致谢。
可能是数组转换什么的问题,建议使用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)
除了颜色模式切换,我没有看到任何其他失真。
我正在用 oop 风格重写我的应用程序,运行 遇到了一个意想不到的问题。调色板图像失真。这以前从未发生过。
class 容器
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
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
class ColorSelector(Frame):
def __init__(self, parent, 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, 3, 251, 251, outline='black', width=4)
self.cursor_obj_id = self.palette.create_oval(81, 81, 71, 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
提前致谢。
可能是数组转换什么的问题,建议使用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)
除了颜色模式切换,我没有看到任何其他失真。