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.


    difference in file-size when using share_image_data(bytesObj) vs. write(bytesObj)

    Pythonista
    5
    6
    1712
    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.
    • tomoto-sauce
      tomoto-sauce last edited by

      I'm having a weird issue when trying to save a PIL image to disk.
      Using the same input data with 2 different save methods, I'm getting significantly different file sizes for the resulting file-on-disk. In the case of very large images (4000px wide), the difference can be as much as 4 MB!

      The process I'm using is exactly the same as the one used in dialogs.share_image_data():

      fileRepr_temp = io.BytesIO()                # create stream to in-memory resource
      pilImg.save(fileRepr_temp, 'PNG' )
      img_data = fileRepr_temp.getvalue()        # get a bytes obj
      

      then afterwards:

      # save to disk using iOS
      (rstr, rlist) = dialogs.share_image_data(img_data)
      
      # save to disk by writing bytes obj to file
      fileRepr = open(pathStr, mode='wb')
      fileRepr.seek(0)
      fileRepr.write(img_data)
      fileRepr.close()
      

      For some reason, the file saved through iOS is significantly smaller than the one created using write(). I'd like to be able to write this same smaller file-size without having to call the iOS dialogue (this is part of a batch-processing script).

      Unfortunately I don't know enough about file IO to understand what's going on here. :(
      Any help would be appreciated!

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

        If I'm not completely wrong, the first variant saves image data in PNG format while the "write" version seems to use raw image data, hence the difference in size. PNG is compressed, the latter is uncompressed.

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

          Png is generally uncompressed. You could use jpg instead, which will be both faster and smaller, though with jpeg artifacts, which may or may not matter depending on what you are saving

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

            I thought the whole goal of PNG was to move to lossless compression that was free of legal constraints https://en.wikipedia.org/wiki/Portable_Network_Graphics#Compression

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

              Png is lossless compressed (or, can be).
              But jpg is MUCH smaller, in that it is losdy compression, and also much faster to convert.

              1 Reply Last reply Reply Quote 0
              • mikael
                mikael @tomoto-sauce last edited by ccc

                @tomoto-sauce, I simulated what share_image_data might be doing and converted the PIL to an ui.Image (UIImage) before saving (#3, below).

                The results... The file sizes of #1 and #3 are the same, and all are PNGs, but in the case of my image, their size was almost 16 MB while the plain byte dump in #2 was about 11 MB. This sounds like the reverse of what you found.

                import io
                
                import dialogs
                import photos
                import ui
                
                
                pil = photos.get_assets()[-1].get_image()
                
                with io.BytesIO() as tmp:
                    pil.save(tmp, 'PNG')
                    img_data = tmp.getvalue()
                    
                # 1
                dialogs.share_image_data(img_data)
                
                # 2
                with open('experiment2.png', mode='wb') as fp:
                    fp.write(img_data)
                
                # 3
                img = ui.Image.from_data(img_data)
                with open('experiment3.png', mode='wb') as fp:
                    fp.write(img.to_png())
                
                1 Reply Last reply Reply Quote 0
                • First post
                  Last post
                Powered by NodeBB Forums | Contributors