Python如何从bytes类型图片中获取宽度和高度
从Bytes类型图片中手动获取宽高的实现方案
以下两种实现均不需要依赖Django ImageField自带的宽高字段功能,性能损耗极低。
方案1:基于Pillow实现(推荐,兼容性最好)
Django使用ImageField时默认已安装Pillow依赖,该方案支持所有主流图片格式,Pillow读取宽高时仅解析图片头部信息,不会加载全图:
from PIL import Image from io import BytesIO import requests # 你原有下载逻辑保持不变 def download_image(url): r = requests.get(url, stream=True) r.raw.decode_content = True return r.content def get_image_dimensions(image_bytes): with BytesIO(image_bytes) as buffer: with Image.open(buffer) as img: # 返回元组格式:(宽度, 高度) return img.size
使用示例:
img_bytes = download_image("图片URL") width, height = get_image_dimensions(img_bytes) # 自行将width、height写入模型自定义的IntegerField字段后,再保存图片到ImageField和S3即可
可按需添加异常捕获逻辑,处理图片损坏、格式不支持的场景。
方案2:无第三方依赖实现(性能最高)
仅使用Python内置库解析图片文件头获取宽高,无需安装任何第三方包,支持JPG、PNG、GIF三种主流格式:
import struct def get_image_dimensions_fast(image_bytes): # 解析PNG格式 if image_bytes.startswith(b'\x89PNG\r\n\x1a\n'): w, h = struct.unpack('>LL', image_bytes[16:24]) return int(w), int(h) # 解析GIF格式 elif image_bytes.startswith(b'GIF87a') or image_bytes.startswith(b'GIF89a'): w, h = struct.unpack('<HH', image_bytes[6:10]) return int(w), int(h) # 解析JPG格式 elif image_bytes.startswith(b'\xff\xd8'): offset = 2 while offset < len(image_bytes): marker, = struct.unpack('>H', image_bytes[offset:offset+2]) offset += 2 if marker == 0xffda: break if 0xffc0 <= marker <= 0xffcf and marker not in (0xffc4, 0xffc8, 0xffcc): h, w = struct.unpack('>HH', image_bytes[offset+3:offset+7]) return int(w), int(h) length, = struct.unpack('>H', image_bytes[offset:offset+2]) offset += length raise ValueError('图片格式不支持或文件已损坏')
内容的提问来源于stack exchange,提问作者Milano
相关产品推荐
相关产品推荐

