如何在 Python 中使用 customtkinter 将自定义角半径应用于 CTkFrame 内的图像?

问题描述 投票:0回答:1

我目前正在使用

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
内的图像?

任何见解或替代方法将不胜感激。谢谢!

python tkinter customtkinter
1个回答
0
投票

我在 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 图片(如上面链接的帖子中所述)。

如果还有更多疑问,可以参考上面的帖子:这里已经有故障排除了。

希望我能帮助到你,祝你有美好的一天。

© www.soinside.com 2019 - 2024. All rights reserved.