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
    6495
    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

      I have a script which uses Pillow to join images - when I call it from Pyhonista itself (with some default images) it runs fine, when I run it (as it is intended) from the Share menu of, say, the Files app, it crashes.

      Problem is I can't find any trace of the crash (no console information or exception backtrace). How can I find out why the script crashed and to what point it got?

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

        @halloleooo, you could explicitly write lines to a file at different points of your script, starting with a version that does nothing much, before adding the image handling.

        pathlib.Path.write_text is a convenient one-liner for this.

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

          @halloleooo I sometimes noticed, in appex mode, that an error was lodged in the console but was hidden by a ui.view. By closing the view, without terminating the program, there was a way to see the log.

          1 Reply Last reply Reply Quote 0
          • 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
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors