'Load an In Memory ZipFile Object to as a KivyImage

I am testing out the ability of loading a zipfile containing multiple images to a kivy image and proofing out that it will cycle through all the images.

I have previously tried out these examples:

https://groups.google.com/forum/#!topic/kivy-users/t_iKvpgLIzE https://kivy.org/docs/api-kivy.core.image.html

I can get these to work, however, I cannot find an example of loading a .zip file or .gif file under those circumstances.

I request to see if it is possible to load a zipfile containing images if the zipfile is located in memory. Or if it's possible to create the animation from images loaded from memory.

import io
import zipfile
from kivy.core.image import Image as CoreImage
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

class testApp(App):

    def get_image_from_memory(self):
        with io.BytesIO(open("archer_F_idle.zip", "rb").read()) as f:
            imgzip = f.read()
            print(imgzip)
            zipped_imgs = zipfile.ZipFile(f)
            print(zipped_imgs, zipped_imgs.namelist(),zipped_imgs.filename)


        return Image(source=zipped_imgs)


    def build(self):
        self.b = BoxLayout()
        self.b.add_widget(self.get_image_from_memory())
        return self.b

if __name__ == '__main__':  
    testApp().run()

Here is the following error:

ValueError: Image.source accept only str


Solution 1:[1]

Here's working example. Make sure you changed zip filename and image exc/filename to yours:

import io
import zipfile
from kivy.core.image import Image as CoreImage
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout


class testApp(App):    
    def get_image_from_memory(self):
        with zipfile.ZipFile("C:/Users/gmn/Downloads/Cover.zip") as myzip:
            with myzip.open('Cover.jpg') as myfile:
                ci = CoreImage(io.BytesIO(myfile.read()), ext="jpg")
                return Image(texture=ci.texture)

    def build(self):
        self.b = BoxLayout()
        self.b.add_widget(self.get_image_from_memory())
        return self.b


if __name__ == '__main__':
    testApp().run()

Upd:

Zip file should contain one or more images.

import io
import zipfile
from itertools import cycle

from kivy.clock import Clock
from kivy.core.image import Image as CoreImage
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty


class ZipAnimationImage(Image):
    zip_source = StringProperty('')

    def __init__(self, **kwargs):
        self._cycle = None
        super(Image, self).__init__(**kwargs)
        Clock.schedule_interval(self._update, 1.0)

    def _update(self, *args):
        if self._cycle:
            self.texture = next(self._cycle).texture

    def on_zip_source(self, *args):
        cis = []
        with zipfile.ZipFile(self.zip_source) as z:
            names = z.namelist()
            for name in names:
                ext = name.split('.')[-1]
                with z.open(name) as f:
                    ci = CoreImage(io.BytesIO(f.read()), ext=ext)
                    cis.append(ci)
        self._cycle = cycle(cis) if cis else None


class testApp(App):
    def build(self):
        self.b = BoxLayout()
        self.b.add_widget(ZipAnimationImage(zip_source='C:/Users/gmn/Downloads/test.zip'))
        return self.b


if __name__ == '__main__':
    testApp().run()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1