How do I open an image from the internet in PIL?

此生再无相见时 提交于 2019-11-28 17:04:24
Snakes and Coffee

You might consider using io.BytesIO for forward compatibility.
The StringIO and cStringIO modules do not exist in Python 3.

from PIL import Image
import urllib2 as urllib
import io

fd = urllib.urlopen("http://a/b/c")
image_file = io.BytesIO(fd.read())
im = Image.open(image_file)

Using your same example, just use StringIO to wrap the buffer into a proper file-like object:

from PIL import Image
import urllib2 as urllib
from StringIO import StringIO

fd = urllib.urlopen("http://a/b/c")
im = Image.open(StringIO(fd.read()))
im.size

Using Python requests:

from PIL import Image
from StringIO import StringIO
import requests

r = requests.get("http://a/b/c")
im = Image.open(StringIO(r.content))
im.size

This pull-request adds support for stream-handling native to Pillow (the friendly PIL fork) and should be available from version 2.8.0. This allows the simpler opening remote files with urllib:

from PIL import Image
import urllib2
Image.open(urllib2.urlopen(url))

...or using requests:

from PIL import Image
import requests
Image.open(requests.get(url, stream=True).raw)

As mentioned by mjpieters on the PR requests does not automatically decode gzip responses, so if you're downloading images that have been further compressed for whatever reason you must set decode_content=True on the response object before accessing .raw.

response = requests.get(url, stream=True)
response.raw.decode_content = True
image = Image.open(response.raw)

The urllib documentation mentions that an object returned by urlopen doesn't support seek operation.

This module provides a high-level interface for fetching data across the World Wide Web. In particular, the urlopen() function is similar to the built-in function open(), but accepts Universal Resource Locators (URLs) instead of filenames. Some restrictions apply — it can only open URLs for reading, and no seek operations are available.

However, the PIL.open function explicitly requires it.

open

Image.open(infile) => image

Image.open(infile, mode) => image

Opens and identifies the given image file. This is a lazy operation; the actual image data is not read from the file until you try to process the data (call the load method to force loading). If the mode argument is given, it must be "r".

You can use either a string (representing the filename) or a file object. In the latter case, the file object must implement read, seek, and tell methods, and be opened in binary mode.

Try using cStringIO module that converts a string into a file-like object.

from PIL import Image
import urllib2 as urllib
import cStringIO

fd = urllib.urlopen("http://a/b/c")
image_file = cStringIO.StringIO(fd.read())
im = Image.open(image_file)
im.size

This answer is 4 years ago, but it's still on top in Google.In Python3, we have simple solution.

from urllib.request import urlopen
img =Image.open(urlopen('http://dl.iplaypython.com/images/banner336x280.jpg'))
new_img =img.resize((300,500),Image.ANTIALIAS)
new_img.save('url.jpg','jpeg')
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!