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.


    Can't add image to clipboard from share sheet extension?

    Pythonista
    pillow clipboard image sharesheet extension
    3
    7
    76
    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.
    • felciano
      felciano last edited by

      Hi --

      I'm trying to use Pythonista 3.4 to push some data to the clipboard, and am running into an error. The code below reproduces the problem: if I am in an app that allows you to share an image (e.g. for a social media post or similar) and I share that image with this Pythonista code, I get the following output:

      Starting test
      Setting clipboard image
      Traceback (most recent call last):
        File "/private/var/mobile/Library/Mobile Documents/iCloud~com~omz-software~Pythonista3/Documents//pythonista-scripts/clipboard-image-test.py", line 24, in <module>
          main()
        File "/private/var/mobile/Library/Mobile Documents/iCloud~com~omz-software~Pythonista3/Documents//pythonista-scripts/clipboard-image-test.py", line 17, in main
          r1 = clipboard.set_image(my_image, format="png", jpeg_quality=1.0)
        File "/var/containers/Bundle/Application/B859D305-94CD-48F6-8589-AE439D2CCB7E/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/pythonista/clipboard.py", line 55, in set_image
          image_data = rgba_image.tostring()
        File "/var/containers/Bundle/Application/B859D305-94CD-48F6-8589-AE439D2CCB7E/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/PIL/Image.py", line 520, in __getattr__
          raise AttributeError(name)
      AttributeError: tostring
      

      It looks like Pythonista's clipboard.py is calling a rgba_image.tostring() method which no longer exists in the version of PIL shipping with Pythonista 3.4.

      Has anyone else seen this? Any suggestions to work around it?

      Thanks!

      Sample code is below.

      import importlib
      import importlib.util
      
      def main():
          print("Starting test")
          # check to see if appex library is available
          appex_spec = importlib.util.find_spec("appex")
          FOUND_APPEX_LIBRARY = appex_spec is not None
          if FOUND_APPEX_LIBRARY:
              import appex
              import clipboard
              import shortcuts
      
              if appex.is_running_extension():
                  my_image = appex.get_image()
                  print("Setting clipboard image")
                  r1 = clipboard.set_image(my_image, format="png", jpeg_quality=1.0)
                  print("Finished setting clipboard image")
                  
              else:
                  print("This demo is for Pythonista running in an extension")
      
      if __name__ == "__main__":
          main()
      
      ccc cvp 2 Replies Last reply Reply Quote 0
      • ccc
        ccc @felciano last edited by

        try:
            import appex
            import clipboard
            import shortcuts
        except ImportError:
            raise Exception("This code only runs on Pythonista on iOS.")
        
        1 Reply Last reply Reply Quote 0
        • cvp
          cvp @felciano last edited by cvp

          @felciano try this workaround

                      my_image = appex.get_image(image_type='ui')
                      print("Setting clipboard image")
                      r1 = clipboard.set_image(my_image, format="png", jpeg_quality=1.0)
                      print("Finished setting clipboard image")
          

          But, you are right, with image_type = 'pil', the default, the clipboard.set_image crashes with error as you described (thus problem for @omz)

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

            Thanks @cvp. That workaround addresses the immediate issue, however now it looks like the Image object returned by

            my_image = appex.get_image(image_type="ui")
            

            is missing methods as well (e.g. my_image.format fails).

            Submitted https://github.com/omz/Pythonista-Issues/issues/702 and https://github.com/omz/Pythonista-Issues/issues/703 for these.

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

              @felciano sure that an ui.Image does not have the methods of a PIL image but the clipboard.set_image allows to save an ui.Image as a format=png

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

                @cvp I need to do other things with the image besides push it to the clipboard. Is there a way to convert it from a "ui" image to a regular "pil" image once, and then use the "pil" version going forward?

                felciano 1 Reply Last reply Reply Quote 0
                • felciano
                  felciano @felciano last edited by

                  OK I think I found a workaround. Ugly, but servicable until this gets fixed in the mainline: I retrieve the share sheet image in PIL format as desired, but then convert it to to "ui" format before pushing to the clipboard. For all other uses, I have a PIL object with all the right methods.

                  In case anyone else runs into this, this code shows the workaround:

                  import importlib
                  import importlib.util
                  import io
                  import ui
                  from PIL import Image
                  
                  def pil2ui(pil_img):
                      with io.BytesIO() as buffer:
                          pil_img.save(buffer, format='PNG')
                          return ui.Image.from_data(buffer.getvalue())
                  
                  def main():
                      print("Starting test")
                      # check to see if appex library is available
                      appex_spec = importlib.util.find_spec("appex")
                      FOUND_APPEX_LIBRARY = appex_spec is not None
                      if FOUND_APPEX_LIBRARY:
                          import appex
                          import clipboard
                          import shortcuts
                  
                          if appex.is_running_extension():
                              my_image = appex.get_image(image_type="pil")
                              # workaround: force to 'ui' format
                              my_new_image = pil2ui(my_image)
                              print("Setting clipboard image")
                              r1 = clipboard.set_image(my_new_image, format="png", jpeg_quality=1.0)
                              print("Finished setting clipboard image")
                              
                          else:
                              print("This demo is for Pythonista running in an extension")
                  
                  if __name__ == "__main__":
                      main()
                  
                  1 Reply Last reply Reply Quote 1
                  • First post
                    Last post
                  Powered by NodeBB Forums | Contributors