Hi,
I am developing an app which, among the other things, needs to display the pictures taken from the camera.
Currently I am using AsyncImage to load and display the images in a specific folder; something like this:
import sys
import glob
import os.path
from kivy.app import App
from kivy.factory import Factory
from kivy.lang import Builder
Builder.load_string('''
<Thumbnail@AsyncImage>:
canvas.before:
Color:
rgb: 0.1, 0.1, 0.1
Rectangle:
pos: self.pos
size: self.size
size_hint: 0.25, None
height: self.width
<PictureGrid@StackLayout>:
spacing: "2dp"
''')
class PicShowApp(App):
def build(self):
root = Factory.PictureGrid()
dirpath = sys.argv[1]
files = glob.glob(os.path.join(dirpath, '*.jpg'))
for f in files:
root.add_widget(Factory.Thumbnail(source=f))
return root
if __name__ == "__main__":
app = PicShowApp()
app.run()
However, I noticed that the process consumes an incredible amount of memory (I measured ~1GB to display 8 3840x2160 images).
I investigated and I saw that even if the AsyncImage widget are tiny, they keep a reference to the whole, full-resolution, uncompressed texture.
One thing I tried was to create the thumbnail whenever we change the texture of AsyncImage:
class MyAsyncImage(AsyncImage):
def on_texture(self, obj, texture):
if texture.size > tuple(self.size):
buf = BytesIO()
texture.save(buf)
buf.seek(0)
img = PILImage.open(buf)
img.thumbnail(self.size)
newtex = texture.create(size=self.size)
newtex.blit_buffer(img.tostring(), colorfmt=img.mode.lower())
self.texture = newtex
self._coreimage = None
However, it doesn't work because I get garbled images. I suppose that I do something wrong to create the texture from the PIL image.
I know that I could simply save the thumbnails on disk and display those (and I might go for this solution after all), but now I would like to know if there is a solution which does not require to save data to disk.
So, basically I have two questions:
1) What is the best way to achieve my goal?
2) What is wrong in the MyAsyncImage example? How do I convert a PIL image to a texture?
thank you,
Antonio