获取图像大小而无需在Python中下载

gro*_*tos 18 python url image

如何在不实际下载的情况下获取图像尺寸?它甚至可能吗?我有一个图像网址列表,我想为它分配宽度和大小.

我知道有一种方法可以在本地进行(如何使用python检查目录中所有图像的尺寸?),但我不想下载所有图像.

编辑:

继编辑.建议,我编辑了代码.我想出了这段代码.不确定天气它下载整个文件或只是一个部分(我想要的).

Jef*_*ffG 17

这是基于ed的答案以及我在网络上发现的其他内容.我和.read(24)遇到了与grotos相同的问题.从下载getimageinfo.py 这里和下载ReSeekFile.py 这里.

import urllib2
imgdata = urllib2.urlopen(href)
image_type,width,height = getimageinfo.getImageInfo(imgdata)
Run Code Online (Sandbox Code Playgroud)

像这样修改getimageinfo ......

import ReseekFile

def getImageInfo(datastream):
    datastream = ReseekFile.ReseekFile(datastream)
    data = str(datastream.read(30))

#Skipping to jpeg

# handle JPEGs
elif (size >= 2) and data.startswith('\377\330'):
    content_type = 'image/jpeg'
    datastream.seek(0)
    datastream.read(2)
    b = datastream.read(1)
    try:
        while (b and ord(b) != 0xDA):
            while (ord(b) != 0xFF): b = datastream.read(1)
            while (ord(b) == 0xFF): b = datastream.read(1)
            if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
                datastream.read(3)
                h, w = struct.unpack(">HH", datastream.read(4))
                break
            else:
                datastream.read(int(struct.unpack(">H", datastream.read(2))[0])-2)
            b = datastream.read(1)
        width = int(w)
        height = int(h)
    except struct.error:
        pass
    except ValueError:
        pass
Run Code Online (Sandbox Code Playgroud)

  • `getimageinfo.py` 的源代码不再可用。以下是供将来寻找它的任何人使用的代码:https://gist.github.com/bmamouri/55ac6bfa7ba5eee03da2eb9e4f7469d9 (2认同)

jed*_*ikb 17

我发现这个网站上的解决方案运行良好:

import urllib
import ImageFile

def getsizes(uri):
    # get file size *and* image size (None if not known)
    file = urllib.urlopen(uri)
    size = file.headers.get("content-length")
    if size: size = int(size)
    p = ImageFile.Parser()
    while 1:
        data = file.read(1024)
        if not data:
            break
        p.feed(data)
        if p.image:
            return size, p.image.size
            break
    file.close()
    return size, None

print getsizes("http://www.pythonware.com/images/small-yoyo.gif")
# (10965, (179, 188))
Run Code Online (Sandbox Code Playgroud)

  • 请注意此代码中的文件描述符:如果检索图像大小,则文件未关闭. (5认同)

ed.*_*ed. 10

如果你愿意下载每个文件的前24个字节,那么这个函数(johnteslade对你提到的问题的回答中提到的)将得出维度.

这可能是完成你想要的工作所需的最少下载.

import urllib2
start = urllib2.urlopen(image_url).read(24)
Run Code Online (Sandbox Code Playgroud)

编辑(1):

在jpeg文件的情况下,它似乎需要更多的字节.您可以编辑该函数,以便不是读取StringIO.StringIO(数据)而是从urlopen读取文件句柄.然后它将读取与查找宽度和高度所需的图像完全相同的图像.


Ale*_*ler 7

这仅仅是一个较早的答案Python的3+适应这里

import urllib
from PIL import ImageFile

def getsizes(uri):
    # get file size *and* image size (None if not known)
    file = urllib.request.urlopen(uri)
    size = file.headers.get("content-length")
    if size: 
        size = int(size)
    p = ImageFile.Parser()
    while True:
        data = file.read(1024)
        if not data:
            break
        p.feed(data)
        if p.image:
            return size, p.image.size
            break
    file.close()
    return(size, None)
Run Code Online (Sandbox Code Playgroud)


Bar*_*aa 6

通过使用请求库:

要获取图像大小(以字节为单位):

仅通过从网站获取标题数据:(无需下载图像)

import requests

url = r"https://www.sulitest.org/files/source/Big%20image%20HD/elyx.png"

size = requests.get(url, stream = True).headers['Content-length']
print(size)
## output: 437495

## to see what other headers data you can get:
allheaders = requests.get(url, stream = True).headers
print(allheaders)
Run Code Online (Sandbox Code Playgroud)

获取图像(宽度、高度):

我们必须下载图像的一部分,并让图像库读取图像标题并检索/解析(宽度,高度)。我在这里使用Pillow

import requests
from PIL import ImageFile

resume_header = {'Range': 'bytes=0-2000000'}    ## the amount of bytes you will download
data = requests.get(url, stream = True, headers = resume_header).content

p = ImageFile.Parser()
p.feed(data)    ## feed the data to image parser to get photo info from data headers
if p.image:
    print(p.image.size) ## get the image size (Width, Height)
## output: (1400, 1536)
Run Code Online (Sandbox Code Playgroud)

  • 这很有魅力! (2认同)

小智 5

由于上述getimageinfo.py在Python3中不起作用。使用枕头代替它。

枕头可在pypi中找到,或使用pip:安装pip install pillow

从io import BytesIO
从PIL导入图片
汇入要求
hrefs = ['https://farm4.staticflickr.com/3894/15008518202_b016d7d289_m.jpg','https://farm4.staticflickr.com/3920/15008465772_383e697089_m.jpg','https://farm4.staticflickr.com/ 3902 / 14985871946_86abb8c56f_m.jpg']
范围= 5000
对于href中的href:
    req = requests.get(href,headers = {'User-Agent':'Mozilla5.0(Google spider)','Range':'bytes = 0-{}'。format(RANGE)})
    im = Image.open(BytesIO(req.content))

    打印(尺寸)

  • 这实际上不是下载图像吗?我相信这就是OP试图避免的 (2认同)

pla*_*aes 1

不可能直接做到这一点,但有一个解决方法。如果服务器上存在文件,则实现 API 端点,该端点将图像名称作为参数并返回大小。

但是,如果文件位于不同的服务器上,则除了下载文件之外,您别无选择。