You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kivy中插入带圆角边框且保持比例的裁剪图片?

解决Kivy中RoundedRectangle图片背景不拉伸、自动裁剪的问题

由于RoundedRectangle本身不支持fit_mode属性,你可以通过以下两种方法实现图片作为圆角背景时保持比例、自动裁剪的效果:

方法一:使用Stencil遮罩结合Image组件

利用Kivy的Stencil模板遮罩功能,先绘制圆角矩形作为遮罩,再在遮罩内放置支持fit_mode的Image组件,既实现圆角效果,又保留图片的比例裁剪。

修改你的kv文件如下:

#:kivy 2.2.1

<CustomImage>:
    # 用Stencil创建圆角遮罩
    canvas.before:
        StencilPush
        RoundedRectangle:
            pos: self.pos
            size: self.size
            radius: [40,]
        StencilUse
    
    # 放置Image组件,使用cover模式裁剪图片
    Image:
        source: "image.jpg"
        fit_mode: "cover"
        size: root.size
        pos: root.pos
        allow_stretch: True
    
    # 清理Stencil遮罩
    canvas.after:
        StencilUnUse
        StencilPop

MyScreen:
    CustomImage:
        size_hint: (0.6, 0.2)
        pos_hint: {"center_x": 0.5, "center_y": 0.5}

方法二:自定义支持cover模式的RoundedRectangle

通过继承RoundedRectangle,手动计算纹理的UV坐标,实现类似cover的裁剪效果,直接在canvas中使用即可。

修改你的Python文件,添加自定义类:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics.vertex_instructions import RoundedRectangle


class CoverRoundedRectangle(RoundedRectangle):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 绑定source和size变化事件,自动更新UV坐标
        self.bind(source=self._update_uv_coords, size=self._update_uv_coords)

    def _update_uv_coords(self, *args):
        if not self.texture:
            return
        
        tex_w, tex_h = self.texture.width, self.texture.height
        rect_w, rect_h = self.width, self.height

        # 计算缩放比例,取较大值保证纹理覆盖整个矩形
        scale = max(rect_w / tex_w, rect_h / tex_h)
        scaled_tex_w = tex_w * scale
        scaled_tex_h = tex_h * scale

        # 计算偏移量,让纹理居中显示
        offset_x = (scaled_tex_w - rect_w) / 2 / scaled_tex_w
        offset_y = (scaled_tex_h - rect_h) / 2 / scaled_tex_h

        # 设置UV坐标,实现裁剪效果
        self.uv_coords = (
            offset_x, offset_y,
            1 - offset_x, offset_y,
            1 - offset_x, 1 - offset_y,
            offset_x, 1 - offset_y
        )


class CustomImage(RelativeLayout):
    pass

class MyScreen(RelativeLayout):
    pass
  
kv = Builder.load_file("draft_question.kv")
  
class MyApp(App):
    def build(self):
        return kv
  
if __name__ == "__main__":
    MyApp().run()

然后修改kv文件,使用自定义的CoverRoundedRectangle:

#:kivy 2.2.1
#:import CoverRoundedRectangle __main__

<CustomImage>:
    canvas.before:
        CoverRoundedRectangle:
            pos: (0,0)
            size: self.size
            source: "image.jpg"
            radius: [40,]

MyScreen:
    CustomImage:
        size_hint: (0.6, 0.2)
        pos_hint: {"center_x": 0.5, "center_y": 0.5}

两种方法都能实现图片作为圆角背景时不拉伸、自动裁剪的效果,你可以根据需求选择。

内容的提问来源于stack exchange,提问作者LupaDevStudio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 04:01:18