我目前正在使用
customtkinter
开发一个 Python 项目,并且在将自定义角半径应用于 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
内的图像?
任何见解或替代方法将不胜感激。谢谢!
我在 stackoverflow 上滚动,发现了这篇文章:如何使用 pil 对没有白色背景(透明?)的徽标进行圆角处理?
这让我想起了4天前我评论过的问题,说在customtkinter中不可能圆角,所以我在这里纠正自己。
确实可以使用 PIL.ImageDraw.drawellipse() 来做到这一点,代码如下:
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 图片(如上面链接的帖子中所述)。
如果还有更多疑问,可以参考上面的帖子:这里已经有故障排除了。
希望我能帮助到你,祝你有美好的一天。