Python - 如何从URL读取图像?

12

我完全是Python的新手,正在尝试弄清楚如何从URL读取图像。

这是我的当前代码:

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)

我收到以下错误:

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

我不知道这些都是什么意思。我做错了什么吗?


3
open() 期望文件名,而不是数据 - 因此您必须先将图像写入本地,然后再打开它 - Image.open('temp.jpg')。或者使用 io.BytesIO 在内存中创建文件对象。 - furas
1
一旦你读取了这张图片,你想要对它做什么? - Daniel Roseman
5个回答

32

Image.open() 期望的是文件名或类似文件的对象,而不是文件数据。

您可以将图像写入本地 - 比如作为"temp.jpg" - 然后打开它。

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

或者您可以使用 io 模块在内存中创建类似文件的对象。

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

编辑:2022年

由于urlopen()也提供了类似文件的对象,因此您甚至可以跳过io直接使用url(而不需要.read())在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()

8

以下是使用scikit-image从URL读取图像的方法:

from skimage import io

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

注意:io.imread() 返回的是一个numpy数组。

2

首先,您可以先将该镜像下载到当前工作目录中

from urllib.request import urlretrieve

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

然后在本地打开/读取:

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

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

img.show()

0

这个Stack Overflow回答中建议的那样,你可以像这样做:

import urllib, cStringIO
from PIL import Image

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

然后您可以自由使用您的图像。 例如,您可以将其转换为numpy数组:

img_npy = np.array(img)

0
我使用这种方法:
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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接