Search code examples
pythonpython-3.xopenglkivykivy-language

Creating a custom image class in Kivy which sets the mag_filter to "nearest"


What am I doing wrong here? I can't get my custom image class to set the mag_filter to "nearest". Pixel images are very blurry, and it's annoying to set the mag_filter individually.

Here's my Python:

#test2.py
import kivy
kivy.require("1.10.0")
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image

class Container(BoxLayout):
    pass

class CustomImage(Image):
    def build(self):
        #self.ids.img.texture.mag_filter = 'nearest'   #doesn't work
        #self.img.texture.mag_filter = 'nearest'       #doesn't work
        self.texture.mag_filter = 'nearest'            #doesn't work
        #texture.mag_filter = 'nearest'                #doesn't work

class TestName(App):
    def build(self):
        global root
        Builder.load_file("picTest.kv")
        root = Container()
        return root

### Keep everything below this last! ###
if __name__ == '__main__':
    TestName().run()

And here's the corresponding Kivy file

#picTest.kv
Container:

#Container holds all the other layouts
<Container>:
    id: contain
    CustomImage:
        source: "smile.png"
    CustomImage:
        source: "smile.png"
    CustomImage:
        source: "smile.png"

<CustomImage>:
    id: img
    allow_stretch: True

"smile.png":

smile.png


Solution

  • You have to do it by making a bind of the texture and in the callback you must change the texture, this connection must be done in the constructor.

    #test2.py
    import kivy
    kivy.require("1.10.0")
    from kivy.app import App
    from kivy.lang import Builder
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.image import Image
    
    class Container(BoxLayout):
        pass
    
    class CustomImage(Image):
        def __init__(self, *args, **kwargs):
            Image.__init__(self, *args, **kwargs)
            self.bind(texture=self._update_texture_filters)
    
        def _update_texture_filters(self, image, texture):
            texture.mag_filter = 'nearest'
    
    class TestName(App):
        def build(self):
            Builder.load_file("picTest.kv")
            root = Container()
            return root
    
    ### Keep everything below this last! ###
    if __name__ == '__main__':
        TestName().run()
    

    Before:

    enter image description here

    After:

    enter image description here