0

I need to download an image when it arrives in Dropbox and upload to Azure Storage. I am doing this using a Kubeless serverless function which is triggered by Dropbox's push notification. This download and upload is working fine. However, I'd like to access the image's exif data so I can send metadata about the image to a RabbitMQ queue. When I try and open the image to use with Python's Pillow or exif modules I get this error: 'UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte'

 dbx = dropbox.Dropbox(os.environ['DROPBOX_TOKEN'])
    for entry in dbx.files_list_folder('').entries:
        print('File found: ' + entry.name)
        md, response = dbx.files_download('/' + entry.name)

        file_stream = response.content

       # Code to upload to Azure Storage and delete file from Dropbox here
       

I've tried:

       with open(file_stream, 'rb') as data:
            # do things with file

And using Pillow:

image = Image.open(file_stream)
        image.show()

And get same error with each. I'm new to using Python and working with files this way so any help would be appreciated.

KCourt
  • 31
  • 2
  • try `image = Image.frombytes('RGBA', (128,128), image_data, 'raw') ` – Bijay Regmi Mar 03 '21 at 14:37
  • assuming its an RGBA image, if not, adjust accordingly. – Bijay Regmi Mar 03 '21 at 14:37
  • Thank you @JackSparrow, this returned an empty object when getting the exif data, but you led me to the solution, which was to use image = Image.open(io.BytesIO(file_stream)). Many thanks – KCourt Mar 03 '21 at 15:16
  • You are welcome, do you mind posting it as answer if it solved the problem? I am sure someone in future will be looking after this. – Bijay Regmi Mar 03 '21 at 16:56

1 Answers1

3

I was trying to open the file, whereas file_stream is already the opened file content.

The Python Request doc's provide an example of using Pillow's Image.open() in a way that works for me:

>>> from PIL import Image
>>> from io import BytesIO

>>> i = Image.open(BytesIO(r.content))

https://2.python-requests.org/en/master/user/quickstart/#binary-response-content

For future reference, this way of opening the image allowed me to access the exif data successfully (img_exif = image.getexif()) whereas the exif data was empty when using Image.fromBytes(). I'm not sure why.

KCourt
  • 31
  • 2