Posts python3 如何只下载少量字节获取网络图片尺寸
Post
Cancel

python3 如何只下载少量字节获取网络图片尺寸

图片的尺寸信息一般都在图片文件的头部几个字节内,所以只下载头部几个字节即可获得图片的尺寸,这也是为什么浏览器在图片还未加载完成即可正确显示图片的尺寸的原因。

使用PIL获取图片尺寸

1
2
3
4
5
6
7
8
from PIL import Image

def get_size(fn):
    try:
        img = Image.open(fn)
        return img.size
    except Exception as e:
        return (0, 0)

使用 requests 下载数据流,使用 BytesIO 把数据流暂存到内存中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from io import BytesIO
import requests
from PIL import Image

def get_size(fn):
    try:
        img = Image.open(fn)
        return img.size
    except Exception:
        return (0, 0)

def stream():
    # 用于保存图片头部字节流
    head = BytesIO()
    # stream=True 表示数据流方式下载
    r = requests.get(
        'https://img30.360buyimg.com/sku/jfs/t1/184915/21/23329/362021/624fa58eE6b2ae8bc/1f17196eb4537d48.jpg', stream=True)
    # 每次下载的数据大小,经测试2KB左右,可以获得图片尺寸的成功率较为理想
    chunk_size = 1024 * 2
    if r.status_code == 200:
        for chunk in r.iter_content(chunk_size):
            head.write(chunk)
            print(get_size(head))
            r.close()

stream()
# 输出结果 (750, 1129)

使用 aiohttp_requests 实现的异步版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from awaits.awaitable import awaitable
from aiohttp_requests import requests as io_requests
import asyncio
from io import BytesIO
from PIL import Image


@awaitable
def get_size(fn):
    try:
        img = Image.open(fn)
        return img.size
    except Exception as e:
        return (0, 0)

async def stream():
    head = BytesIO()
    chunk_size = 1024 * 2
    url = 'https://img30.360buyimg.com/sku/jfs/t1/184915/21/23329/362021/624fa58eE6b2ae8bc/1f17196eb4537d48.jpg'
    r = await io_requests.get(url)
    if r.status == 200:
        is_first = True
        async for chunk in r.content.iter_chunked(chunk_size):
            head.write(chunk)
            size = await get_size(head)
            print(size)
            await r.wait_for_close()
            break

asyncio.run(stream())

邀请您关注我的公众号,我将会不时地为您推送独家原创的技术内容分享。
This post is licensed under CC BY 4.0 by the author.

Trending Tags