Python Image.open() gives 'object has no attribute' error

11,747

After much googling and experimenting I have found a good solution. The following code also ensures the image is properly rotated.

def xformpics(self):
    conn = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
    bucket = conn.get_bucket(settings.AWS_STORAGE_BUCKET_NAME)

    for key in bucket.list(prefix='media/userphotos'):

        # Get the image to be resized from the S3 bucket
        file_name=key.name
        full_path_filename = 'https://' + settings.AWS_STORAGE_BUCKET_NAME + '.s3.amazonaws.com/' + file_name
        fd_img = urlopen(full_path_filename);
        img = Image.open(fd_img)

        # Check EXIF data to see if image needs to be rotated
        img = image_transpose_exif(img)

        # Resize the image to a width of 800 (for viewing on a web page)
        img = resizeimage.resize_width(img, 800)

        # Upload the resized image to the S3 bucket
        new_filename = full_path_filename.replace('userphotos', 'webversion')
        img.save('temp.jpg', img.format)
        with open('temp.jpg', 'rb') as data:
            r = requests.put(new_filename, data, auth=S3Auth(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY))

        fd_img.close()

def image_transpose_exif(im):
    exif_orientation_tag = 0x0112  # contains an integer, 1 through 8
    exif_transpose_sequences = [  # corresponding to the following
        [],
        [Image.FLIP_LEFT_RIGHT],
        [Image.ROTATE_180],
        [Image.FLIP_TOP_BOTTOM],
        [Image.FLIP_LEFT_RIGHT, Image.ROTATE_90],
        [Image.ROTATE_270],
        [Image.FLIP_TOP_BOTTOM, Image.ROTATE_90],
        [Image.ROTATE_90],
    ]

    try:
        seq = exif_transpose_sequences[im._getexif()[exif_orientation_tag] - 1]
    except Exception:
        return im
    else:
        return functools.reduce(lambda im, op: im.transpose(op), seq, im)

Share:
11,747
Bill Noble
Author by

Bill Noble

Updated on June 04, 2022

Comments

  • Bill Noble
    Bill Noble almost 2 years

    I am trying to use requests.get() to open/get a file for image processing but my code falls over when I try to do an Image.open() with the file I have just got.

    My code is:

    conn = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
    bucket = conn.get_bucket(settings.AWS_STORAGE_BUCKET_NAME)
    
    for key in bucket.list(prefix='media/userphotos'):
        file_name=key.name
        full_path_filename = 'https://' + settings.AWS_STORAGE_BUCKET_NAME + '.s3.amazonaws.com/' + file_name
        fd_img = requests.get(full_path_filename);
        img = Image.open(fd_img)
        img = resizeimage.resize_width(img, 800)
        new_filename = file_name
        new_filename.replace('userphotos', 'webversion')
        full_path_filename =  'https://' + settings.AWS_STORAGE_BUCKET_NAME + '.s3.amazonaws.com/' + new_filename
        img.save(full_path_filename, img.format)
        fd_img.close()
    

    The traceback is: 
    
    Traceback:
    
    File "/Users/billnoble/Documents/YHistory-Server/yhistoryvenv/lib/python3.4/site-packages/PIL/Image.py" in open
      2275.         fp.seek(0)
    
    During handling of the above exception ('Response' object has no attribute 'seek'), another exception occurred:
    
    File "/Users/billnoble/Documents/YHistory-Server/yhistoryvenv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
      149.                     response = self.process_exception_by_middleware(e, request)
    
    File "/Users/billnoble/Documents/YHistory-Server/yhistoryvenv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
      147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
    
    File "/Users/billnoble/Documents/YHistory-Server/items/views.py" in xformpics
      67.         img = Image.open(fd_img)
    
    File "/Users/billnoble/Documents/YHistory-Server/yhistoryvenv/lib/python3.4/site-packages/PIL/Image.py" in open
      2277.         fp = io.BytesIO(fp.read())
    
    Exception Type: AttributeError at /xformpics
    Exception Value: 'Response' object has no attribute 'read'

    It all works fine up to the Image.open().

    I have spent many hours googling this issue but cannot find a solution.

  • Bill Noble
    Bill Noble over 7 years
    Yes that seems to be the case. How can I get a file object with something like requests.get(). I would use open() but that only works on local files and my file is on the internet.
  • Bill Noble
    Bill Noble over 7 years
    I tried your suggestion: fd_img = requests.get(full_path_filename).text; img = Image.fromstring(fd_img)) But Image.fromstring() falls over
  • John Gordon
    John Gordon over 7 years
    I believe both fromstring() and frombuffer() require extra arguments. You'd have to read the documentation to find out how to use them correctly.