Python Image.open()给出'object has no attribute'错误

时间:2021-10-25 07:29:11

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.

我正在尝试使用requests.get()打开/获取文件进行图像处理,但是当我尝试使用我刚刚获得的文件执行Image.open()时,我的代码就会崩溃。

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().

这一切都适用于Image.open()。

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

我花了很多时间在谷歌搜索这个问题,但无法找到解决方案。

2 个解决方案

#1


1  

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)

#2


0  

Image.open() requires a file (or file-like) object, which the result of requests.get() is not.

Image.open()需要一个文件(或类文件)对象,而request.get()的结果则不需要。

You probably want to slurp the image content into a buffer:

您可能希望将图像内容粘贴到缓冲区中:

image_data = requests.get(full_path_filename).text

And then use Image.fromstring() or Image.frombuffer() to use the buffer, rather than a file, to create an image.

然后使用Image.fromstring()或Image.frombuffer()来使用缓冲区而不是文件来创建图像。

#1


1  

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)

#2


0  

Image.open() requires a file (or file-like) object, which the result of requests.get() is not.

Image.open()需要一个文件(或类文件)对象,而request.get()的结果则不需要。

You probably want to slurp the image content into a buffer:

您可能希望将图像内容粘贴到缓冲区中:

image_data = requests.get(full_path_filename).text

And then use Image.fromstring() or Image.frombuffer() to use the buffer, rather than a file, to create an image.

然后使用Image.fromstring()或Image.frombuffer()来使用缓冲区而不是文件来创建图像。