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.


    How to debug crash of image script when it's called as extension

    Pythonista
    4
    29
    7017
    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.
    • halloleooo
      halloleooo last edited by

      @mikael @cvp Thanks for the suggestions. I will try them.

      My own investigation shows, the issue seems to be related to memory use of the images. Not really big stuff, but the size seems to be the culprit:

      • When I use 2 images with 1MB each it crashes.
      • When I use 2 images with 10Kb each it works.

      All 4 images come from the Files app.

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

        @halloleooo, from what I read, share extensions should have a 120 MB memory limit, not sure how much Pythonista takes.

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

          @mikael Mmmh, interesting. So why does my share extension crashes with (mere) 1MB images???

          cvp 2 Replies Last reply Reply Quote 0
          • cvp
            cvp @halloleooo last edited by

            @halloleooo advice: if you want to join photos, don't run in appex mode and use photos module to pick two images. We always have had memory problems with big photos in appex mode.

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

              @halloleooo I think that a pil image of 10000x10000 pixels uses 10000x10000x4 bytes = 400 MB
              even if your compressed jpeg is a 6MB file

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

                @cvp Aha! that makes total sense!

                But how can I not run in appex mode, but still join images from anywhere? I thought that's what share extensions are for...

                cvp 3 Replies Last reply Reply Quote 0
                • cvp
                  cvp @halloleooo last edited by

                  @halloleooo perhaps find a way without passing via pil, for example, via ui.image_context?

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

                    @halloleooo if you want a join of original pictures, I think that even ui.image_context will use a lot of memory, but if you want a smaller jointed image, it could be possible to work with resized images.

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

                      @halloleooo please, try this one in the share sheet

                      import appex
                      import ui
                      import io
                      from PIL import Image
                      
                      def pil2ui(imgIn):
                      	with io.BytesIO() as bIO:
                      		imgIn.save(bIO, 'PNG')
                      		imgOut = ui.Image.from_data(bIO.getvalue())
                      		del bIO
                      	return imgOut
                      
                      ui_images = []	
                      
                      # assume two images are shared
                      files = appex.get_attachments()
                      for f in files:
                      	pil = Image.open(f)#,mode='r')
                      	ui_image = pil2ui(pil)
                      	del pil
                      	w,h = ui_image.size
                      	wi = 400
                      	hi = wi*h/w
                      	with ui.ImageContext(wi,hi) as ctx:
                      		ui_image.draw(0,0,wi,hi)
                      		del ui_image
                      		ui_resize = ctx.get_image()
                      		ui_images.append(ui_resize)
                      		del ui_resize		
                      	
                      w1,h1 = ui_images[0].size
                      w2,h2 = ui_images[1].size
                      # assume images have same height
                      with ui.ImageContext(w1+w2,h1) as ctx:
                      	ui_images[0].draw(0,0,w1,h1)
                      	ui_images[1].draw(w1,0,w2,h2)
                      	ui_image_joined = ctx.get_image()
                      w,h = ui_image_joined.size
                      v = ui.ImageView()
                      v.frame = (0,0,400,400*h/w)
                      v.content_mode = ui.CONTENT_SCALE_ASPECT_FIT
                      v.image = ui_image_joined
                      v.present('')
                      
                      halloleooo 1 Reply Last reply Reply Quote 0
                      • halloleooo
                        halloleooo @cvp last edited by

                        @cvp Thanks for the detailed script.

                        One thing I am wondering about is: You get the images from the share extension as PIL images via

                        appex.get_attachments()
                        

                        and then convert them to UI images. Isn't there a way to get them directly as UI images? I thought UI image is the iOS-native format...

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

                          @halloleooo you're right but we got some problems with images in appex mode, thus...
                          Else, I use this where you can set type you want

                          img = appex.get_image(image_type='pil')
                          
                          1 Reply Last reply Reply Quote 0
                          • JonB
                            JonB last edited by

                            Doesn't appex provide a get_ui_image function? That will be much lighter weight than going through PIL and back.

                            cvp 1 Reply Last reply Reply Quote 1
                            • cvp
                              cvp @JonB last edited by cvp

                              @JonB sure, he knows that, but in the past, we got some problems with it.

                              Édit: believe me, if we go through pil, it is not for the pleasure to do it.

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

                                @cvp So what are the problems with get_ui_image?

                                cvp 2 Replies Last reply Reply Quote 0
                                • cvp
                                  cvp last edited by

                                  Correction: appex does not have a get_ui_image

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

                                    We mixed with asset.get_ui_image

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

                                      I have been disturbed only because the post comes from @JonB

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

                                        @halloleooo doc dixit, you could try with

                                        img = appex.get_image(image_type='ui')
                                        
                                        #files = appex.get_attachments()
                                        #for f in files:
                                        files = appex.get_images(image_type='ui')
                                        for ui_image in files:
                                        	#pil = Image.open(f)#,mode='r')
                                        	#ui_image = pil2ui(pil)
                                        	#del pil
                                        
                                        1 Reply Last reply Reply Quote 0
                                        • halloleooo
                                          halloleooo last edited by ccc

                                          I think the Pyhonista docs mentions appex.get_ui_image(). Is this wrong?

                                          cvp 5 Replies Last reply Reply Quote 0
                                          • cvp
                                            cvp @halloleooo last edited by

                                            @halloleooo modif just above also crashes with two big photos...

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