ฉันจะอ่านข้อมูลรูปภาพจาก URL ใน Python ได้อย่างไร


182

สิ่งที่ฉันพยายามทำนั้นค่อนข้างง่ายเมื่อเราจัดการกับไฟล์ในเครื่อง แต่ปัญหาเกิดขึ้นเมื่อฉันพยายามทำสิ่งนี้ด้วย URL ระยะไกล

โดยพื้นฐานแล้วฉันกำลังพยายามสร้างวัตถุรูปภาพ PIL จากไฟล์ที่ดึงมาจาก URL แน่นอนว่าฉันสามารถดึง URL และเก็บไว้ในไฟล์ temp ได้เสมอจากนั้นเปิดเป็นวัตถุรูปภาพ แต่รู้สึกไม่มีประสิทธิภาพมาก

นี่คือสิ่งที่ฉันมี:

Image.open(urlopen(url))

มันสะบัดออกบ่นที่seek()ไม่สามารถใช้ได้ดังนั้นฉันลองนี้:

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

แต่นั่นก็ไม่ได้ผลเช่นกัน มีวิธีที่ดีกว่าในการทำเช่นนี้หรือเขียนไปยังแฟ้มชั่วคราวเป็นวิธีที่ได้รับการยอมรับในการทำสิ่งนี้?


คำตอบ:


282

ใน Python3 โมดูล StringIO และ cStringIO หายไป

ใน Python3 คุณควรใช้:

from PIL import Image
import requests
from io import BytesIO

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

วิธีการรับภาพจากการตอบกลับเนื้อหา?
Amresh Giri

requestsแพคเกจโยนรหัสสถานะ 503 ในขณะที่ดึงภาพจาก URL ฉันต้องหันไปhttp.clientใช้ภาพแทน
Manishankar Singh

เมื่อฉันลองสิ่งนี้ฉันจะได้รับ: AttributeError: โมดูล 'คำร้องขอ' ไม่มีแอตทริบิวต์ 'รับ'
apiljic

2
การห่อด้วย BytesIO ด้วยตนเองนั้นไม่จำเป็นอีกต่อไปตั้งแต่ PIL> = 2.8.0 Image.open(response.raw)ใช้เพียงแค่ PIL จะตรวจสอบโดยอัตโนมัติในขณะนี้และทำการ BytesIO ที่อยู่ใต้ฮูด จาก: pillow.readthedocs.io/en/3.0.x/releasenotes/2.8.0.html
Vinícius M

ขอบคุณ YOUUUUUUUUUUUUU, OP
Sharl Sherif

166

คุณสามารถลองใช้ StringIO

import urllib, cStringIO

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

ขอขอบคุณเพียงแค่ต้องการเพิ่มว่ารหัสที่แน่นอนเดียวกันจะทำงานกับ urllib2 (กับ Python2)
เบา ๆ

17
ในไพ ธ อน 3 มันจะมาจาก urllib.request urlopen นำเข้าและ io.io.BytesIO แทนที่จะเป็น StringIO
matyas

2
ความช่วยเหลือ IOError: ไม่สามารถระบุไฟล์รูปภาพ <_io.BytesIO วัตถุที่ 0x7fb91b6a29b0> URL ของฉันคือ: ... model = product.template & id = 16 & field = image_medium
С. Дэлг18рцэцэг

56

ฉันใช้ไลบรารีคำขอ ดูเหมือนว่าจะแข็งแกร่งขึ้น

from PIL import Image
import requests
from StringIO import StringIO

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

3
ด้วยเหตุผลบางอย่าง urllib ใช้ไม่ได้กับ URL บางตัว แต่คำขอทำงานในที่ที่ล้มเหลว
mirri66

ฉันหาแพ็คเกจ PIL ไม่ได้ แต่ดูเหมือนว่าหมอนได้ผ่าน PIL มาแล้วและคุณสามารถติดตั้งสำหรับ python3 pip3.4 install pillowได้
ก่อกวน

3
โปรดทราบว่าคำขอจะโหลดการตอบสนองทั้งหมดลงในหน่วยความจำจากนั้น PIL จะโหลดสิ่งทั้งหมดอีกครั้งในฐานะภาพดังนั้นคุณจึงมีสำเนาสองชุดที่มีถิ่นที่อยู่ในหน่วยความจำ คำตอบก่อนหน้านี้โดยใช้วิธี urllib จะทำการสตรีมข้อมูลดังนั้นคุณจะจบลงด้วยการทำสำเนาหนึ่งชุดพร้อมกับขนาดบัฟเฟอร์การสตรีม คุณสามารถสตรีมข้อมูลด้วยคำขอได้เช่นกัน แต่เนื่องจากการตอบสนองไม่รองรับซีแมนทิกส์ read () คุณจึงต้องสร้างอะแดปเตอร์
sirdodger

@sirdodger คุณหมายถึง urllib2 หรือ urllib หรือไม่?
CMCDragonkai

@CMCDragonkai ฉันหมายถึงคำตอบที่ยอมรับ urllib หากปัญหาเกี่ยวกับค่าใช้จ่ายของหน่วยความจำจะดีกว่าการใช้คำตอบคำขอนี้ (อย่างไรก็ตามอย่างที่ได้กล่าวไปแล้วการแก้ปัญหาที่แตกต่างกันโดยใช้การร้องขออาจทำให้ได้ผลที่เหมือนกัน)
sirdodger

42

สำหรับผู้ที่ใช้หมอนจากรุ่น 2.8.0 คุณสามารถ:

from PIL import Image
import urllib2

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

หรือถ้าคุณใช้requests:

from PIL import Image
import requests

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

อ้างอิง:


27

ใช้StringIOเพื่อเปลี่ยนสตริงการอ่านให้เป็นวัตถุเหมือนไฟล์:

from StringIO import StringIO
import urllib

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

21

สำหรับผู้ที่ทำการโพสต์ sklearn / numpy (เช่นการเรียนรู้ลึก) คุณสามารถล้อมวัตถุ PIL ด้วย np.array () สิ่งนี้อาจช่วยให้คุณไม่ต้องไปที่ Google เหมือนที่ฉันทำ:

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 และ IPython

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

แตกต่างจากวิธีอื่นวิธีนี้ยังทำงานใน for for loop!


12

เนื้อหาที่แนะนำวิธีการทำภาพที่นำเข้า / ส่งออกวันนี้คือการใช้แพคเกจเฉพาะImageIO ข้อมูลรูปภาพสามารถอ่านได้โดยตรงจาก URL ด้วยรหัสบรรทัดเดียว:

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

คำตอบมากมายในหน้านี้มีมาก่อนการเปิดตัวแพคเกจนั้นจึงไม่ได้กล่าวถึง ImageIO เริ่มต้นจากส่วนประกอบของชุดเครื่องมือScikit-Image มันสนับสนุนจำนวนของรูปแบบทางวิทยาศาสตร์ด้านบนของคนที่มีให้โดยเป็นที่นิยมการประมวลผลภาพห้องสมุดหมอน มันล้อมรอบทั้งหมดใน API แบบคลีนที่เน้นเฉพาะอินพุต / เอาต์พุตรูปภาพเท่านั้น ในความเป็นจริง SciPy ลบออกเองภาพอ่าน / เขียนของตนในความโปรดปรานของ ImageIO


3

เลือกภาพในโครเมี่ยมคลิกขวาที่มันคลิกที่ Copy image addressวางไว้ในstrตัวแปร ( my_url) เพื่ออ่านภาพ:

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

เปิด;

from PIL import Image

img = Image.open('my_image.png')
img.show()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.