omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    scene updating every second

    Pythonista
    4
    17
    7916
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • jmv38
      jmv38 last edited by

      hello
      i am trying to animate a series of png images computed with pythonista. I would like to display 1 image every second, and record the film with the ipad record, so i try to customize the scene example of the doc. But nothing works, i keep getting stupid errors, probably my bad.
      Can anyone help? Thanks.

      1 Reply Last reply Reply Quote 0
      • jmv38
        jmv38 last edited by

        here is a code with no error, but the view_update is never called

        # coding: utf-8
        from scene import *
        import ui
        import photos
        from PIL import Image
        import io as io
        def pil2ui(pil_img):
            with io.BytesIO() as buffer:
                pil_img.save(buffer, format='PNG')
                return ui.Image.from_data(buffer.getvalue())
        
        def view_update():
              azim -= 10
              file = 'CieLuv_'+str(azim)+'.png'
              print(file)
              im = Image.open(file)
              ui_image = pil2ui(im)
                  
        
        class MyScene (Scene):
            global ui_image,t0,azim
            
            def setup(self):
                self.background_color = 'ligtgray'
                img = ui.Button(name='image')
                img.frame = (25, 50, 1476/1.5, 1024/1.5) #1476 1024
                img.background_image = ui_image
                img.enable = False
                img.hidden = False
                self.view.add_subview(img)
        
                # trying to update 1 per second
                self.view.update_interval = 1
                self.view.update = view_update
                
            def disp_photo(self,sender):
                img = sender.superview['image']
                img.hidden = not img.hidden
                
        if __name__ == '__main__':
            global ui_image, azim
            im = Image.open("CieLuv_-10.png")
            ui_image = pil2ui(im)
            azim = 190
            
            run(MyScene())
        
        
        cvp 1 Reply Last reply Reply Quote 0
        • cvp
          cvp @jmv38 last edited by cvp

          @jmv38 the refresh method of a scene is update. You have mixed with view.update of an ui.View.
          See animation sub-folder of examples

          Perhaps it could be better that instead of a Scene, you use a ui.View.
          In this cases, setup becomes the init, and the code of your view_update can be put in def update of the custom view class.

          see here

          jmv38 1 Reply Last reply Reply Quote 0
          • jmv38
            jmv38 @cvp last edited by

            @cvp thanks, i’ll have a look.
            The problem is that with Scene or ui.View some fair amount a background is needed to get it work smoothly. I wish i could just tweek a couple lines in an example and get what i need. The built in example are a bit too complex for that.
            Thanks anyway. And happy new year!

            1 Reply Last reply Reply Quote 0
            • jmv38
              jmv38 last edited by jmv38

              also searching in the forum with keywords really leads me nowhere. The search engine does not seem very smart, cause i am fairly sure i saw that kind of problems disucussed in the past, but i dont get any usefull link...

              mikael 1 Reply Last reply Reply Quote 0
              • jmv38
                jmv38 last edited by

                with scene + update, how can i trigger something once per second? When i try to use globals to keep track of a global state t, i keep getting some ‘local variable t used before being assigned’ , although it is global and assigned in the main... I pbly dont get fully how python namespaces work or in which order things are called, so i am stuck.

                1 Reply Last reply Reply Quote 0
                • jmv38
                  jmv38 last edited by

                  btw, for anyone interested, here is the kind of video i want to make
                  https://youtu.be/eXBGYHKKytI
                  this one i made by assembling the images manually with Splice, i am trying to make it more automatic.

                  1 Reply Last reply Reply Quote 0
                  • mikael
                    mikael @jmv38 last edited by

                    @jmv38, if you use a View, you can set its update_interval to 1 (second), and its update method gets automatically called once per second.

                    Also, for better results, use Google to search instead of the forum search.

                    1 Reply Last reply Reply Quote 0
                    • JonB
                      JonB last edited by JonB

                      you want to avoid globals in Scenes -- make those variables methods of your scene. The way threads work in scene, I think as written you could have issues.

                      by the way, most scene examples use run(amyScene()), but you are allowed to do:

                      s=MyScene(someparams,that,your,init,accepts)
                      s.someattrib=value
                      run(s)
                      1 Reply Last reply Reply Quote 0
                      • JonB
                        JonB last edited by

                        Also, take a look at the scene docs.
                        You need to implement either a draw method, which is called once per frame (and you would use scene_drawing.image method, using a set of images where you prefiously called load_pil_image to precache inages), or else you would use update to set spritenode texture. the scene.run method takes a frame_interval parameter to set fps.

                        you may define a custom init that sets scene attributes etc based on globals -- but setup might not have access to globals (not sure if this is still true -- but it does run in a separate thread). Use setup just to handle actual display stuff,

                        Depending in how many images you have, it might be worth creating all your SpriteNodes up front.

                        1 Reply Last reply Reply Quote 0
                        • jmv38
                          jmv38 last edited by jmv38

                          thanks for your advices. I chose to go for the ui.view. It worked nicely https://youtu.be/Li5gV2tUj5M
                          (make sure to set 1080p when you watch the video, otherwise the quality is bad)

                          mikael 1 Reply Last reply Reply Quote 0
                          • jmv38
                            jmv38 last edited by

                            here is the code

                            import ui
                            from console import clear
                            from PIL import Image
                            import io as io
                            def pil2ui(pil_img):
                                with io.BytesIO() as buffer:
                                    pil_img.save(buffer, format='PNG')
                                    return ui.Image.from_data(buffer.getvalue())
                            
                            class MyView (ui.View):
                              def __init__(self):
                                # global view settings
                                self.name = 'Viewing where colors lie in the CIE L*u*v* color space'                                    
                                self.background_color = 'gray'     
                                # trying to update 1 per second
                                self.update_interval = 1
                                
                                # image settings
                                img = ui.Button(name='image')
                                img.width = 1476/1.5
                                img.height = 1024/1.5
                                img.enable = False
                                img.hidden = False
                                self.add_subview(img)
                                self.img = img
                                
                                # add a copyright
                                txt = ui.Label()
                                txt.text = 'copyright JMV38 2019'
                                txt.text_color = (0.5, 0.5, 0.5, 0.2)
                                txt.width = 600
                                txt.height = 100
                                txt.alignment = ui.ALIGN_CENTER
                                fontName, fontSize = txt.font
                                txt.font = (fontName,30)
                                self.add_subview(txt)
                                self.txt = txt
                                
                              def update(self):
                                self.img.center = (self.width * 0.5, self.height * 0.5)
                                self.txt.center = (self.width * 0.5, self.height * 0.5)
                                try:
                                  self.azim -= 10
                                except:
                                  self.azim = 180
                                file = 'CieLuv_'+str(self.azim)+'.png'
                                try:
                                  print(file)
                                  im = Image.open(file)
                                  ui_image = pil2ui(im)
                                  self.img.background_image = ui_image
                                except:
                                  exit()
                                
                            if __name__ == '__main__':
                              clear()
                              view = MyView()      
                              view.present('full_screen')  
                              
                            
                            1 Reply Last reply Reply Quote 0
                            • mikael
                              mikael @jmv38 last edited by

                              @jmv38, nice! Have you tried updating every 1/30 or even 1/60 sec and making it completely smooth?

                              jmv38 1 Reply Last reply Reply Quote 0
                              • jmv38
                                jmv38 @mikael last edited by jmv38

                                @mikael actually
                                1/ i have not computed enough intermediate frames (each take 30s on my ipad air)
                                2/ i use the video to view it frame by frame from the ipad photo roll, to turn around as i wish, so it is enough for my usage
                                3/ i have tried 0.5s once but it skipped 1 frame in the middle, so i thought i would remain at 1 Hz.
                                thanks.

                                1 Reply Last reply Reply Quote 0
                                • jmv38
                                  jmv38 last edited by jmv38

                                  still in trouble.
                                  I am trying to save my numpy structured array with np.save, here is the code for details

                                  # differents tests avec Luv
                                  
                                  from labColor import *
                                  import numpy as np
                                  from console import clear
                                  # compute all colors
                                  
                                  def getAllColors(step):
                                    dtype = [('L', float), ('u', float), ('v', float), ('c', tuple), ('d', float)]
                                    data = []
                                    for r in np.arange(0, 256, step):
                                      print(r)
                                      for g in np.arange(0, 256, step):
                                        for b in np.arange(0, 256, step):
                                          L, u, v = rgb_to_sLuv(r, g, b)
                                          data.append((L, u, v, (r/255,g/255,b/255), 0.0))
                                    ar = np.array(data,dtype=dtype)
                                    return ar
                                  
                                  clear()
                                  ar = getAllColors(50)
                                  print(len(ar))
                                  print(ar.dtype)
                                  np.save('rgb.npy',ar)
                                  a = np.load('rgb.npy')
                                  print(len(a))
                                  print(a.dtype)
                                  

                                  but i get this error

                                  Traceback (most recent call last):
                                    File "/private/var/mobile/Containers/Shared/AppGroup/..../Pythonista3/Documents/couleurs/labColor6.py", line 24, in <module>
                                      np.save('rgb.npy',ar)
                                    File "/var/containers/Bundle/Application/..../Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/numpy/lib/npyio.py", line 451, in save
                                      format.write_array(fid, arr)
                                    File "/var/containers/Bundle/Application/.../Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/numpy/lib/format.py", line 407, in write_array
                                      pickle.dump(array, fp, protocol=2)
                                  _pickle.PicklingError: Can't pickle <built-in function _reconstruct>: import of module 'multiarray' failed
                                  

                                  what am i doing wrong?
                                  thanks

                                  1 Reply Last reply Reply Quote 0
                                  • jmv38
                                    jmv38 last edited by

                                    ok i got it. numpy.save cannot decode tuples by itself...
                                    surprising that there is no simple way to save a structured array, and that i must flatten the structure to save it. Extra work and risk of errors... Anyway...

                                    1 Reply Last reply Reply Quote 0
                                    • jmv38
                                      jmv38 last edited by

                                      here is another video, technically more useful
                                      https://youtu.be/6Qi0UBBXZVw

                                      1 Reply Last reply Reply Quote 1
                                      • First post
                                        Last post
                                      Powered by NodeBB Forums | Contributors