Kivy - Atlas



If your app is expected to work with many images, especially on a remote server, their loading time needs to be optimized. Atlas in Kivy framework helps in reducing the loading time. With Kivy Atlas, the app needs to load just one image file, which is less error prone, and also uses lesser resources than loading several images. The Atlas is often used in Kivy games apps for rendering images.

The Atlas class is available in the "kivy.atlas" module. This module can be used to construct an Atlas object programmatically, as well as with its command-line interface.

To be able to use Atlas, the current Kivy environment must have the pillow package - an image library for Python. If not available, install it using −

pip3 install pillow

An Atlas is made up of two files −

  • A json file (it has ".atlas" extension) that contains the image file names and texture locations of the atlas.

  • The image files containing textures referenced by the ".atlas" file.

Assuming that the following images are in a directory called imges −

Directory of C:\kivyenv\images

forward.png    pause.png    play.png    previous.png

Each of these images is of 64×64 pixels dimension. Hence, we designate an atlas file 0f 256×256 pixels size to accommodate all the four files. Open the command terminal of your OS and run the command −

python -m kivy.atlas myatlas 256x256 *.png

The terminal shows following log information, at the end of which the two files will be created in the images folder.

(kivyenv) C:\kivyenv\images>python -m kivy.atlas myatlas 256x256 *.png
[INFO  ] [Logger   ] Record log in C:\Users\mlath\.kivy\logs\kivy_23-07-20_33.txt
[INFO  ] [deps     ] Successfully imported "kivy_deps.gstreamer" 0.3.3
[INFO  ] [deps     ] Successfully imported "kivy_deps.angle" 0.3.3
[INFO  ] [deps     ] Successfully imported "kivy_deps.glew" 0.3.1
[INFO  ] [deps     ] Successfully imported "kivy_deps.sdl2" 0.6.0
[INFO  ] [Kivy     ] v2.2.0
[INFO  ] [Kivy     ] Installed at "c:\kivyenv\Lib\sitepackages\kivy\__init__.py"
[INFO  ] [Python   ] v3.11.2 (tags/v3.11.2:878ead1, Feb 7 2023, 16:38:35) [MSC v.1934 64 bit (AMD64)]
[INFO  ] [Python   ] Interpreter at "c:\kivyenv\Scripts\python.exe"
[INFO  ] [Logger   ] Purge log fired. Processing...
[INFO  ] [Logger   ] Purge finished!
[DEBUG ] STREAM b'IHDR' 16 13
[DEBUG ] STREAM b'sRGB' 41 1
[DEBUG ] STREAM b'gAMA' 54 4
[DEBUG ] STREAM b'pHYs' 70 9
[DEBUG ] STREAM b'IDAT' 91 1115
[DEBUG ] STREAM b'IHDR' 16 13
[DEBUG ] STREAM b'sRGB' 41 1
[DEBUG ] STREAM b'gAMA' 54 4
[DEBUG ] STREAM b'pHYs' 70 9
[DEBUG ] STREAM b'IDAT' 91 990
[DEBUG ] STREAM b'IHDR' 16 13
[DEBUG ] STREAM b'sRGB' 41 1
[DEBUG ] STREAM b'gAMA' 54 4
[DEBUG ] STREAM b'pHYs' 70 9
[DEBUG ] STREAM b'IDAT' 91 1230
[INFO  ] [Atlas   ] create an 256x256 rgba image
Atlas created at myatlas.atlas
1 image has been created

You can see that two additional files created are myatlas-0.png, which is a 256×256 file comprising of all the images, and an atlas file.

forward.png    myatlas-0.png    myatlas.atlas    pause.png
play.png
previous.png

The ".atlas" file is a JSON file containing the information of texture locations of constituent files.

{"myatlas-0.png": {"forward": [2, 190, 64, 64], "pause": [68, 190, 64, 64], "play": [134, 190, 64, 64], "previous": [2, 124, 64, 64]}}

In order to use the Atlas in the Kivy language, we have to use the following format −

atlas://path/to/atlas/atlas_name/id. 

The "id" file refers to the image filename without the extension.

For example, if you want to use an image file as a button background in normal state, you would do it as follows −

B1 = Button(background_normal='images/play.png')
Now, aAfter generating the Atlas, you can use the URL
'atlas://images/myatlas/play' as the value.
B1=Button(background_normal='atlas://images/myatlas/play')

Note that in the atlas url, there is no need to add the .atlas extension. It will be automatically appended to the filename.

Example

Let us the image URLs from the Atlas to set the normal backgrounds for the four buttons - play, pause, forward and previous - on the app window.

The atlas files must be created as shown above before running the following code −

from kivy.app import App
from kivy.graphics import *
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.core.window import Window
Window.size = (720, 400)

class AtlasApp(App):
   def build(self):
      main = GridLayout(cols=1)
      self.l1 = Label(text='Using Atlas', font_size=32)
      main.add_widget(self.l1)
      root = FloatLayout(size=(Window.width, 100))
      with root.canvas:
         Color(.2, .7, .1, 1)
         Rectangle(pos=root.pos, size=root.size)
      
      self.btn1 = Button(
         size_hint=(None, None),
         pos_hint={'center_x': .2, 'center_y': .2}
      )
      self.btn2 = Button(
         size_hint=(None, None),
         pos_hint={'center_x': .4, 'center_y': .2}
      )
      
      self.btn3 = Button(
         size_hint=(None, None),
         pos_hint={'center_x': .6, 'center_y': .2}
      )
      
      self.btn4 = Button(
         size_hint=(None, None),
         pos_hint={'center_x': .8, 'center_y': .2}
      )
      self.btn1.background_normal = 'atlas://images/myatlas/forward'
      self.btn2.background_normal = 'atlas://images/myatlas/play'
      self.btn3.background_normal = 'atlas://images/myatlas/pause'
      self.btn4.background_normal = 'atlas://images/myatlas/previous'
      
      root.add_widget(self.btn1)
      root.add_widget(self.btn2)
      root.add_widget(self.btn3)
      root.add_widget(self.btn4)
      
      main.add_widget(root)
      return main
AtlasApp().run()

Output

When you run this code, it will produce the following output window −

Kivy Atlas
Advertisements