Je voudrais retrouver les dimensions d'une image sur internet. J'ai essayé d'utiliser
from PIL import Image
import urllib2 as urllib
fd = urllib.urlopen("http://a/b/c")
im = Image.open(fd)
im.size
comme suggéré dans cette réponse , mais je reçois le message d'erreur
addinfourl instance has no attribute 'seek'
J'ai vérifié et les objets retournés par urllib2.urlopen(url)
ne semblent pas avoir de méthode de recherche selon dir
.
Alors, que dois-je faire pour pouvoir charger une image d'Internet dans PIL?
Vous pourriez envisager d'utiliser io.BytesIO
pour compatibilité ascendante .
Les modules StringIO et cStringIO n'existent pas dans 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)
En utilisant votre même exemple, utilisez simplement StringIO pour envelopper le tampon dans un objet de type fichier approprié:
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
Utilisation de 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
Cette pull-request ajoute la prise en charge de la gestion des flux native de Pillow (la fourchette PIL conviviale) et devrait être disponible à partir de la version 2.8.0. Cela permet d'ouvrir des fichiers distants plus simplement avec rllib :
from PIL import Image
import urllib2
Image.open(urllib2.urlopen(url))
... ou en utilisant requêtes :
from PIL import Image
import requests
Image.open(requests.get(url, stream=True).raw)
Comme mentionné par mjpieters sur le PR les requêtes ne décodent pas automatiquement les réponses gzip
, donc si vous téléchargez des images qui ont été encore compressées pour une raison quelconque, vous devez définir decode_content=True
sur l'objet réponse avant d'accéder à .raw
.
response = requests.get(url, stream=True)
response.raw.decode_content = True
image = Image.open(response.raw)
La documentation urllib
mentionne qu'un objet renvoyé par urlopen
ne prend pas en charge l'opération seek
.
Ce module fournit une interface de haut niveau pour récupérer des données sur le World Wide Web. En particulier, la fonction urlopen () est similaire à la fonction intégrée open (), mais accepte les URL (Universal Resource Locators) au lieu des noms de fichiers. Certaines restrictions s'appliquent - il ne peut ouvrir que des URL pour la lecture et aucune opération de recherche n'est disponible.
Cependant, le PIL.open
la fonction l'exige explicitement.
ouvert
Image.open (infile) => image
Image.open (infile, mode) => image
Ouvre et identifie le fichier d'image donné. Il s'agit d'une opération paresseuse; les données d'image réelles ne sont pas lues à partir du fichier jusqu'à ce que vous essayiez de traiter les données (appelez la méthode de chargement pour forcer le chargement). Si l'argument mode est donné, il doit être "r".
Vous pouvez utiliser une chaîne (représentant le nom de fichier) ou un objet fichier. Dans ce dernier cas, l'objet fichier doit implémenter les méthodes de lecture, de recherche et de lecture , et être ouvert en mode binaire.
Essayez d'utiliser le module cStringIO
qui convertit une chaîne en objet de type fichier.
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