如何在Python的customtkinter中对CTkFrame内的图像应用自定义圆角半径?
我现在在做一个Python项目,使用的是customtkinter
库,但遇到了一个问题:我想给一个放在CTkFrame
里的图片加上圆角,但没成功。下面是我代码的一个简单示例:
import customtkinter
from PIL import Image
image_path = #image path
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
frame = customtkinter.CTkFrame(self, width=200, height=111, corner_radius=5)
frame.pack()
image = customtkinter.CTkImage(Image.open(image_path), size=(200, 111))
image_label = customtkinter.CTkLabel(frame, image=image, text="")
image_label.pack()
if __name__ == "__main__":
app = App()
app.mainloop()
在这段代码中,我试图在CTkFrame
里显示一张图片,并给它设置圆角。但是,图片并没有跟随父框架的圆角,反而是尖尖的角。
我尝试用画布来给图片加上圆角遮罩,但这样做出来的圆角分辨率很低,而且有时候圆角和背景不太匹配。
请问我该如何正确地给CTkFrame
里的图片加上自定义的圆角呢?
如果有任何建议或其他方法,我会非常感激。谢谢!
1 个回答
0
我在StackOverflow上浏览时发现了这个帖子:如何使用PIL让logo的角变圆,而不在它上面留下白色背景(透明的?)
这让我想起了我四天前评论过的你的问题,我当时说在customtkinter中不可能让角变圆,所以我来这里纠正一下自己。
其实,使用PIL.ImageDraw.Draw.ellipse()
是可以做到的,下面是代码:
from PIL import Image, ImageDraw
def add_corners(im, rad):
circle = Image.new('L', (rad * 2, rad * 2), 0)
draw = ImageDraw.Draw(circle)
draw.ellipse((0, 0, rad * 2 - 1, rad * 2 - 1), fill=255)
alpha = Image.new('L', im.size, 255)
w, h = im.size
alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0))
alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad))
alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0))
alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad))
im.putalpha(alpha)
return im
在你的情况下,完整的代码是:
import customtkinter
from PIL import Image, ImageDraw
image_path = #image path
def add_corners(im, rad):
circle = Image.new('L', (rad * 2, rad * 2), 0)
draw = ImageDraw.Draw(circle)
draw.ellipse((0, 0, rad * 2 - 1, rad * 2 - 1), fill=255)
alpha = Image.new('L', im.size, 255)
w, h = im.size
alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0))
alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad))
alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0))
alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad))
im.putalpha(alpha)
return im
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
frame = customtkinter.CTkFrame(self, width=200, height=111, corner_radius=5)
frame.pack()
image = customtkinter.CTkImage(add_corners(Image.open(image_path), 100), size=(200, 111))
image_label = customtkinter.CTkLabel(frame, image=image, text="")
image_label.pack()
if __name__ == "__main__":
app = App()
app.mainloop()
不过,如果你想要透明背景,这个方法只适用于.png格式的图片(就像上面链接的帖子中提到的那样)。
如果你还有其他问题,可以参考上面的帖子:那里已经有解决方案了。
希望我能帮到你,祝你有个愉快的一天。
补充:因为我觉得让角变圆很有用,我创建了一个模块,里面有一个类来自动化这个功能,这个模块叫做MoreCustomTkinterWidgets,可以在Pypi上找到。