如何在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
相关产品推荐
相关产品推荐

