Wie lese ich Bilddaten von einer URL in Python?

180

Was ich versuche, ist ziemlich einfach, wenn es sich um eine lokale Datei handelt, aber das Problem tritt auf, wenn ich versuche, dies mit einer Remote-URL zu tun.

Grundsätzlich versuche ich, ein PIL-Bildobjekt aus einer Datei zu erstellen, die von einer URL abgerufen wird. Sicher, ich könnte die URL immer einfach abrufen und in einer temporären Datei speichern und dann in einem Bildobjekt öffnen, aber das fühlt sich sehr ineffizient an.

Folgendes habe ich:

Image.open(urlopen(url))

Es seek()fällt aus, sich zu beschweren, dass es nicht verfügbar ist, also habe ich Folgendes versucht:

Image.open(urlopen(url).read())

Aber das hat auch nicht funktioniert. Gibt es einen besseren Weg, dies zu tun, oder ist das Schreiben in eine temporäre Datei der akzeptierte Weg, um so etwas zu tun?

Daniel Quinn
quelle

Antworten:

277

In Python3 sind die Module StringIO und cStringIO weg.

In Python3 sollten Sie Folgendes verwenden:

from PIL import Image
import requests
from io import BytesIO

response = requests.get(url)
img = Image.open(BytesIO(response.content))
Andres Kull
quelle
Wie bekomme ich das Bild von response.content zurück?
Amresh Giri
requestsDas Paket gibt beim Abrufen eines Bildes von einer URL den Statuscode 503 aus. Stattdessen musste ich zurückgreifen http.client, um das Bild zu erhalten.
Manishankar Singh
Wenn ich das versuche, erhalte ich: AttributeError: Modul 'Anfragen' hat kein Attribut 'Get'.
Apiljic
1
Das manuelle Umschließen in BytesIO ist nicht mehr erforderlich, da PIL> = 2.8.0. Einfach benutzen Image.open(response.raw). PIL prüft dies jetzt automatisch und wickelt das BytesIO unter die Haube. Von: pillow.readthedocs.io/en/3.0.x/releasenotes/2.8.0.html
Vinícius M
DANKE YOUUUUUUUUUUUU, OP.
Sharl Sherif
166

Sie könnten versuchen, ein StringIO zu verwenden

import urllib, cStringIO

file = cStringIO.StringIO(urllib.urlopen(URL).read())
img = Image.open(file)
Fábio Diniz
quelle
Vielen Dank, möchte nur hinzufügen, dass der gleiche genaue Code mit urllib2 (mit Python2)
funktioniert
17
in Python 3 wäre es von urllib.request import urlopen und io.io.BytesIO anstelle von StringIO
matyas
2
HILFE, IOError: Bilddatei <_io.BytesIO-Objekt bei 0x7fb91b6a29b0> kann nicht identifiziert werden. Meine URL lautet: ... model = product.template & id = 16 & field = image_medium
С. 3лгэрцэцэг
56

Ich benutze die Anforderungsbibliothek. Es scheint robuster zu sein.

from PIL import Image
import requests
from StringIO import StringIO

response = requests.get(url)
img = Image.open(StringIO(response.content))
Saurav
quelle
3
Aus irgendeinem Grund funktionierte urllib für einige URLs nicht, aber Anfragen funktionierten dort, wo dies fehlschlug
mirri66
Ich konnte das PIL-Paket nicht finden, aber es sieht so aus, als hätte Pillow die PIL-Anstrengung übernommen und Sie können es mit Python3 installieren pip3.4 install pillow.
störend
3
Beachten Sie, dass Anforderungen die gesamte Antwort in den Speicher laden und PIL dann das gesamte Objekt erneut als Bild lädt, sodass zwei vollständige Kopien im Speicher gespeichert sind. Bei der vorherigen Antwort mit der urllib-Methode werden die Daten gestreamt, sodass Sie nur eine Kopie plus die Größe des Streaming-Puffers erhalten. Sie können die Daten auch mit Anforderungen streamen. Da die Antwort jedoch keine read () -Semantik unterstützt, müssen Sie einen Adapter erstellen.
Sirdodger
@sirdodger Beziehen Sie sich auf urllib2 oder urllib?
CMCDragonkai
@CMCDragonkai Ich bezog mich auf die akzeptierte urllib-Antwort. Wenn der Speicheraufwand ein Problem darstellt, ist es besser, als diese Anforderungsantwort zu verwenden. (Wie ich bereits erwähnt habe, könnte eine andere Lösung mit Anfragen den gleichen Effekt erzielen.)
Sirdodger
42

Für diejenigen unter Ihnen, die Pillow verwenden, können Sie ab Version 2.8.0:

from PIL import Image
import urllib2

im = Image.open(urllib2.urlopen(url))

oder wenn Sie verwenden requests:

from PIL import Image
import requests

im = Image.open(requests.get(url, stream=True).raw)

Verweise:

Giovanni Cappellotto
quelle
27

Verwenden Sie StringIOdiese Option , um die gelesene Zeichenfolge in ein dateiähnliches Objekt umzuwandeln:

from StringIO import StringIO
import urllib

Image.open(StringIO(urllib.requests.urlopen(url).read()))
Dan D.
quelle
21

Für diejenigen, die eine sklearn / numpy-Nachbearbeitung durchführen (dh Deep Learning), können Sie das PIL-Objekt mit np.array () umschließen. Dies könnte Sie davon abhalten, Google wie ich zu müssen:

from PIL import Image
import requests
import numpy as np
from StringIO import StringIO

response = requests.get(url)
img = np.array(Image.open(StringIO(response.content)))
Ben
quelle
19

Python 3

from urllib.request import urlopen
from PIL import Image

img = Image.open(urlopen(url))
img

Jupyter Notebook und IPython

import IPython
url = 'https://newevolutiondesigns.com/images/freebies/colorful-background-14.jpg'
IPython.display.Image(url, width = 250)

Im Gegensatz zu anderen Methoden funktioniert diese Methode auch in einer for-Schleife!

Miladiouss
quelle
12

Die wohl empfohlene Methode zur Eingabe / Ausgabe von Bildern ist heutzutage die Verwendung des dedizierten Pakets ImageIO . Bilddaten können mit einer einfachen Codezeile direkt von einer URL gelesen werden:

from imageio import imread
image = imread('https://cdn.sstatic.net/Sites/stackoverflow/img/logo.png')

Viele Antworten auf dieser Seite stammen aus der Zeit vor der Veröffentlichung dieses Pakets und werden daher nicht erwähnt. ImageIO wurde als Bestandteil des Scikit-Image- Toolkits gestartet . Es unterstützt eine Reihe wissenschaftlicher Formate zusätzlich zu denen der beliebten Bildverarbeitungsbibliothek PILlow . Es verpackt alles in eine saubere API, die sich ausschließlich auf die Bildeingabe / -ausgabe konzentriert. In der Tat, SciPy entfernt sein eigenes Bild - Leser / Schreiber für ImageIO .

anon
quelle
3

Wählen Sie das Bild in Chrom aus, klicken Sie mit der rechten Maustaste darauf, klicken Sie auf Copy image addressund fügen Sie es in eine strVariable ( my_url) ein, um das Bild zu lesen:

import shutil
import requests

my_url = 'https://www.washingtonian.com/wp-content/uploads/2017/06/6-30-17-goat-yoga-congressional-cemetery-1-994x559.jpg'
response = requests.get(my_url, stream=True)
with open('my_image.png', 'wb') as file:
    shutil.copyfileobj(response.raw, file)
del response

öffne es;

from PIL import Image

img = Image.open('my_image.png')
img.show()
Shivid
quelle