Come posso leggere i dati delle immagini da un URL in Python?


182

Quello che sto cercando di fare è abbastanza semplice quando abbiamo a che fare con un file locale, ma il problema si presenta quando provo a farlo con un URL remoto.

Fondamentalmente, sto cercando di creare un oggetto immagine PIL da un file estratto da un URL. Certo, potrei sempre recuperare l'URL e memorizzarlo in un file temporaneo, quindi aprirlo in un oggetto immagine, ma mi sembra molto inefficiente.

Ecco cosa ho:

Image.open(urlopen(url))

Si stacca lamentandosi che seek()non è disponibile, quindi ho provato questo:

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

Ma neanche quello ha funzionato. Esiste un modo migliore per farlo o scrivere su un file temporaneo è il modo accettato di fare questo genere di cose?


Risposte:


281

In Python3 i moduli StringIO e cStringIO sono spariti.

In Python3 dovresti usare:

from PIL import Image
import requests
from io import BytesIO

response = requests.get(url)
img = Image.open(BytesIO(response.content))

Come recuperare l'immagine da response.content?
Amresh Giri,

requestsil pacchetto genera 503 codice di stato durante il recupero di un'immagine da un URL. Invece, ho dovuto ricorrere a http.clientper ottenere l'immagine.
Manishankar Singh,

Quando provo questo ottengo: AttributeError: il modulo 'request' non ha alcun attributo 'get'.
apiljic,

2
Il wrapping manuale in BytesIO non è più necessario poiché PIL> = 2.8.0. Basta usare Image.open(response.raw). PIL ora lo controlla automaticamente e esegue il wrapping BytesIO sotto il cofano. Da: pillow.readthedocs.io/en/3.0.x/releasenotes/2.8.0.html
Vinícius M

GRAZIE TUUUUUUUUUUUU, OP.
Sharl Sherif,

166

potresti provare a usare StringIO

import urllib, cStringIO

file = cStringIO.StringIO(urllib.urlopen(URL).read())
img = Image.open(file)

Grazie, vorrei solo aggiungere che lo stesso codice esatto funzionerà con urllib2 (con Python2)
leggermente il

17
in Python 3 sarebbe da urllib.request import urlopen e io.io.BytesIO invece di StringIO
matyas

2
HELP, IOError: impossibile identificare il file immagine <_io.BytesIO oggetto su 0x7fb91b6a29b0> il mio url è: ... model = product.template & id = 16 & field = image_medium
С. Дэлгэрцэцэг

56

Uso la libreria delle richieste. Sembra essere più robusto.

from PIL import Image
import requests
from StringIO import StringIO

response = requests.get(url)
img = Image.open(StringIO(response.content))

3
Per qualche ragione urllib non ha funzionato per alcuni URL, ma le richieste hanno funzionato dove non è riuscito
mirri66

Non sono riuscito a trovare il pacchetto PIL, ma sembra che il cuscino abbia preso il controllo dello sforzo PIL e che tu possa installarlo con python3 pip3.4 install pillow.
dirompente il

3
Si noti che le richieste caricheranno l'intera risposta in memoria, quindi PIL caricherà di nuovo l'intera cosa come immagine, in modo da avere due copie complete residenti in memoria. La risposta precedente utilizzando il metodo urllib trasmette i dati in streaming, quindi si ottiene solo una copia più la dimensione del buffer di streaming. È anche possibile eseguire lo streaming dei dati con richieste, ma poiché la risposta non supporta la semantica read (), è necessario creare un adattatore.
sirdodger,

@sirdodger Ti riferisci a urllib2 o urllib?
CMCDragonkai,

@CMCDragonkai Mi riferivo alla risposta urllib accettata. Se l'overhead della memoria è un problema, è meglio che utilizzare questa risposta alle richieste. (Tuttavia, come ho già detto, una soluzione diversa che utilizza le richieste potrebbe ottenere lo stesso effetto.)
sirdodger


27

Utilizzare StringIOper trasformare la stringa di lettura in un oggetto simile a un file:

from StringIO import StringIO
import urllib

Image.open(StringIO(urllib.requests.urlopen(url).read()))

21

Per coloro che eseguono un po 'di post sklearn / intorpidimento (ad es. Deep learning) puoi avvolgere l'oggetto PIL con np.array (). Questo potrebbe salvarti dal dover farlo su Google come ho fatto io:

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

19

Python 3

from urllib.request import urlopen
from PIL import Image

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

Jupyter Notebook e IPython

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

A differenza di altri metodi, questo metodo funziona anche in un ciclo for!


12

Il modo discutibilmente raccomandato di fare input / output delle immagini in questi giorni è usare il pacchetto dedicato ImageIO . I dati delle immagini possono essere letti direttamente da un URL con una semplice riga di codice:

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

Molte risposte in questa pagina precedono il rilascio di quel pacchetto e quindi non lo menzionano. ImageIO è nato come componente del toolkit Scikit-Image . Supporta numerosi formati scientifici oltre a quelli forniti dalla famosa libreria di elaborazione delle immagini PILlow . Avvolge il tutto in un'API pulita focalizzata esclusivamente sull'input / output delle immagini. In effetti, SciPy ha rimosso il proprio lettore / scrittore di immagini a favore di ImageIO .


3

seleziona l'immagine in Chrome, fai clic destro su di essa, fai clic su Copy image address, incollala in una strvariabile ( my_url) per leggere l'immagine:

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

aprilo;

from PIL import Image

img = Image.open('my_image.png')
img.show()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.