Last active
July 4, 2022 21:39
-
-
Save benni12er/95a45eb168fc33a4fcd2d545af692dad to your computer and use it in GitHub Desktop.
Kivy image fit crop in frame/layout automatically
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@Nobby89 https://kivy.org/doc/stable/api-kivy.uix.image.html?highlight=asyncimage#kivy.uix.image.AsyncImage