10

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
  • 153
  • 1
  • 2
  • 10
  • 2
    `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

4 Answers4

27

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

You can write image locally - ie 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()
furas
  • 119,752
  • 10
  • 94
  • 135
7

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
  • 506
  • 1
  • 7
  • 14
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
  • 563
  • 4
  • 13