12

I am completely new to Python and I'm trying to figure out how to read an image from a URL.

Here is my current code:

from PIL import Image
import urllib.request, io

URL = 'http://www.w3schools.com/css/trolltunga.jpg'

with urllib.request.urlopen(URL) as url:
    s = url.read()
    Image.open(s)

I get the following error:

C:\python>python image.py
Traceback (most recent call last):
  File "image.py", line 8, in <module>
    Image.open(s)
  File "C:\Anaconda3\lib\site-packages\PIL\Image.py", line 2272, in open
    fp = builtins.open(filename, "rb")
ValueError: embedded null byte

I have no idea what any of this means. What am I doing wrong?

connoraw
  • 173
  • 1
  • 2
  • 11
  • 3
    `open()` expects file name, not data - so you have to write image locally and then open it - `Image.open('temp.jpg')`. Or use io.BytesIO to create file object in memory. – furas Dec 01 '16 at 12:56
  • 1
    What do you want to do with the image once you have read it? – Daniel Roseman Dec 01 '16 at 12:57

5 Answers5

31

Image.open() expects filename or file-like object - not file data.

You can write image locally - i.e. as "temp.jpg" - and then open it

from PIL import Image
import urllib.request

URL = 'http://www.w3schools.com/css/trolltunga.jpg'

with urllib.request.urlopen(URL) as url:
    with open('temp.jpg', 'wb') as f:
        f.write(url.read())

img = Image.open('temp.jpg')

img.show()

Or you can create file-like object in memory using io module

from PIL import Image
import urllib.request
import io

URL = 'http://www.w3schools.com/css/trolltunga.jpg'

with urllib.request.urlopen(URL) as url:
    f = io.BytesIO(url.read())

img = Image.open(f)

img.show()

EDIT: 2022

Because urlopen() also gives file-like object so you can even skip io and use directly url (without .read()) in Image.open()

from PIL import Image
import urllib.request

URL = 'http://www.w3schools.com/css/trolltunga.jpg'

with urllib.request.urlopen(URL) as url:
    img = Image.open(url)
    img.show()
furas
  • 134,197
  • 12
  • 106
  • 148
8

Here's how to read an image from a URL using scikit-image

from skimage import io

io.imshow(io.imread("http://www.w3schools.com/css/trolltunga.jpg"))
io.show()

Note: io.imread() returns a numpy array

ngub05
  • 566
  • 1
  • 8
  • 15
2

To begin with, you may download the image to your current working directory first

from urllib.request import urlretrieve

url = 'http://www.w3schools.com/css/trolltunga.jpg'
urlretrieve(url, 'pic.jpg')

And then open/read it locally:

from PIL import Image
img = Image.open('pic.jpg')

# For example, check image size and format
print(img.size)
print(img.format)

img.show()
mikeqfu
  • 329
  • 2
  • 10
0

As suggested in this stack overflow answer, you can do something like this:

import urllib, cStringIO
from PIL import Image

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

Then you can use your image freely. For example, you can convert it to a numpy array:

img_npy = np.array(img)
Community
  • 1
  • 1
caspillaga
  • 573
  • 4
  • 16
0

I use this approach:

import urllib.request
from io import BytesIO
import matplotlib.pyplot as plt

URL = 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/161px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg'

with urllib.request.urlopen(URL) as url:
    imgfile = BytesIO(url.read())
    img = plt.imread(imgfile,format='jpeg')

plt.imshow(img)
G M
  • 20,759
  • 10
  • 81
  • 84