如何使用aiohttp异步获取图片并直接处理,无需存盘计算哈希?
异步下载图片并计算哈希(无需存盘)
问题背景
用同步requests库可以直接把响应的原始流传入Image.open()处理图片并计算哈希,但改用aiohttp做异步请求时,直接分段处理响应内容会触发ValueError: embedded null byte错误,目前只能先把图片存盘再处理,不符合服务器无存储的需求。
错误原因
response.content是异步迭代器,每次迭代返回的是图片的部分字节数据,而Image.open()需要接收完整的图片字节流或类文件对象,传入分段字节数据会导致图片解析失败。
解决方法
收集完整的图片字节数据,用io.BytesIO包装成类文件对象,再传入Image.open()处理,全程在内存中完成,无需写入磁盘。
修正后的代码
import asyncio import imagehash from PIL import Image from io import BytesIO from aiohttp import ClientSession async def get_aio_picture(): url = 'https://ae01.alicdn.com/kf/Sec174725eb944b4693342178da975d52z.jpg' async with ClientSession() as session: async with session.get(url=url) as response: response.auto_decompress = False # 读取完整的图片字节数据 image_data = await response.read() # 将字节数据包装为类文件对象 img = Image.open(BytesIO(image_data)) hash_val = imagehash.phash(img, hash_size=6) print(f'hash: {hash_val}') async def main(): await get_aio_picture() def aio_hash(): asyncio.run(main())
代码说明
await response.read():一次性读取完整的响应字节数据,替代分段迭代,确保拿到完整的图片文件内容BytesIO(image_data):把字节数据包装成类文件对象,模拟文件流行为,满足Image.open()的参数要求- 全程在内存中完成图片解析与哈希计算,无需磁盘存储操作
内容的提问来源于stack exchange,提问作者ICE
相关产品推荐
相关产品推荐

