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.


    Pythonista crashes trying to save merged photo

    Pythonista
    4
    18
    7188
    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.
    • jm2466
      jm2466 last edited by

      Thanks!!

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

        I added the del image after it is pasted into the merged image and that part appears to work. The program is now having a problem saving the merged image to the camera roll. If I instead save it to the Pythonista file system it works and is a workaround until the camera roll save is figured out. Any other thoughts on how to fix the camera roll save is greatly appreciated.

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

          Do you have a GitHub repo? It is more difficult to debug English prose that it is to debug Python code.

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

            Unfortunately I do not.

            But if you look at the code in my original post I added one line in the for loop to delete the image (below is the loop from that post with the del at the end)

                for im in images:
                    # paste in the image at the left edge (x=0) and current offset for y
                    new_im.paste(im, (0,y_offset))
                    print(f'y_offset = {y_offset}')
                    # increase the offset by the height of current pic
                    y_offset += im.size[1]
                    del im 
            

            As mentioned that seemed to fix the issue pasting more than a few images into the new one.

            This line crashes Pythonista:

                photos.save_image(new_im)
            

            But I can save it to the Pythonista file system with the following:

                new_im.save('combined.jpg')
            
            1 Reply Last reply Reply Quote 0
            • ccc
              ccc last edited by

              This is long shot but:

              del new_img
              photos.save(Image.open('combined.jpg'))
              
              1 Reply Last reply Reply Quote 0
              • jm2466
                jm2466 last edited by

                Thanks. I tried that but it crashes trying to save the image to the camera roll. I can open the jpg in Pythonista and manually add it to the camera roll. Here are the lines at the end that I added:

                	new_im.save('combined.jpg')
                	del new_im
                	photos.save_image(Image.open('combined.jpg'))
                
                
                cvp 1 Reply Last reply Reply Quote 0
                • cvp
                  cvp @jm2466 last edited by cvp

                  @jm2466 I'm in holiday, thus perhaps not able to correctly understand all (🍷🍷) but why did you not use

                  photos.create_image_asset(path)
                  

                  instead of

                  photos.save_image(Image.open(path))
                  
                  1 Reply Last reply Reply Quote 0
                  • jm2466
                    jm2466 last edited by jm2466

                    Um... because you never told me to until now??? :) kidding of course. But honestly have no real answer to that question. Possibly because I wanted to save an in-memory image and not have to save the file locally first (at least that was the initial plan but is not where I am at with it now). Not sure if create image asset supports that (I tried passing the variable and got an error that a str is required).

                    I just tried your suggestion and it works - I mean it saves the locally saved combined.jpg to the camera roll. Thanks!!!

                    Any thoughts on how to get this to work without saving combined.jpg first???

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

                      @jm2466 You could always convert your PIL Image into an ui.Image and use this kind of code to save it in camera roll

                      # only to have an ui.Image
                      import ui
                      img = ui.Image.named('test:Bridge')
                      
                      # Create a PHAsset from an ui.Image (not from a PIL Image)
                      from objc_util import *
                      import threading
                      
                      NSBundle.bundleWithPath_('/System/Library/Frameworks/Photos.framework').load()
                      PHPhotoLibrary = ObjCClass('PHPhotoLibrary')
                      PHAssetChangeRequest = ObjCClass('PHAssetChangeRequest')
                      
                      lib = PHPhotoLibrary.sharedPhotoLibrary()
                      def change_block():
                          req = PHAssetChangeRequest.creationRequestForAssetFromImage_(img)
                      def perform_changes():
                          lib.performChangesAndWait_error_(change_block, None)
                      
                      t = threading.Thread(target=perform_changes)
                      t.start()
                      t.join()
                      
                      1 Reply Last reply Reply Quote 1
                      • cvp
                        cvp @jm2466 last edited by cvp

                        @jm2466 this

                            # 1) convert PIL Image to ui.Image
                            console.hud_alert('convert PIL Image into ui.Image')
                            with io.BytesIO() as bIO:
                                new_im.save(bIO, 'PNG')
                                ui_image = ui.Image.from_data(bIO.getvalue())
                            del bIO
                            # 2) Create a PHAsset from an ui.Image (not from a PIL Image)
                            console.hud_alert('Create a PHAsset from an ui.Image')
                            lib = PHPhotoLibrary.sharedPhotoLibrary()
                            def change_block():
                                req = PHAssetChangeRequest.creationRequestForAssetFromImage_(ui_image)
                            def perform_changes():
                                lib.performChangesAndWait_error_(change_block, None)
                            t = threading.Thread(target=perform_changes)
                            t.start()
                            t.join()
                        

                        is about (😀) 1000 x slower than

                            path = 'temp.jpg'
                            new_im.save(path , quality=95)
                            photos.create_image_asset(path)
                            os.remove(path)
                        
                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        Powered by NodeBB Forums | Contributors