Skip to content

Instantly share code, notes, and snippets.

@benni12er
Last active July 4, 2022 21:39
Show Gist options
  • Select an option

  • Save benni12er/95a45eb168fc33a4fcd2d545af692dad to your computer and use it in GitHub Desktop.

Select an option

Save benni12er/95a45eb168fc33a4fcd2d545af692dad to your computer and use it in GitHub Desktop.
Kivy image fit crop in frame/layout automatically
from kivy.graphics.context_instructions import Color
from kivy.graphics.vertex_instructions import Rectangle
from kivy.properties import StringProperty, Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.uix.widget import Widget
"""
By Benedikt Zwölfer
Example usage:
BoxLayout:
size_hint_y: None
height: dp(200)
orientation: 'vertical'
FitImage:
size_hint_y: 3
source: 'images/img1.jpg'
FitImage:
size_hint_y: 1
source: 'images/img2.jpg'
Works with KivyMD
"""
class FitImage(BoxLayout):
source = StringProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self._late_init)
def _late_init(self, *args):
self.container = Container(self.source)
self.add_widget(self.container)
class Container(Widget):
def __init__(self, source, **kwargs):
super().__init__(**kwargs)
self.bind(size=self.adjust_size)
self.image = Image(source=source)
def adjust_size(self, *args):
(par_x, par_y) = self.parent.size
if par_x == 0 or par_y == 0:
with self.canvas:
self.canvas.clear()
return
par_scale = par_x / par_y
(img_x, img_y) = self.image.texture.size
img_scale = img_x / img_y
if par_scale > img_scale:
(img_x_new, img_y_new) = (img_x, img_x / par_scale)
else:
(img_x_new, img_y_new) = (img_y * par_scale, img_y)
crop_pos_x = (img_x - img_x_new) / 2
crop_pos_y = (img_y - img_y_new) / 2
subtexture = self.image.texture.get_region(crop_pos_x, crop_pos_y, img_x_new, img_y_new)
with self.canvas:
self.canvas.clear()
Color(1, 1, 1)
Rectangle(texture=subtexture, pos=self.pos, size=(par_x, par_y))
@Nobby89
Copy link

Nobby89 commented Apr 22, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment