使用PIL调整图片大小后上传至DigitalOcean Spaces遇BadDigest错误
问题
使用boto3将图片上传至DigitalOcean Spaces时,未加入PIL处理一切正常。但在Django视图中调用resize_maintain_its_aspect_ratio方法(哪怕只执行Image.open(image))后,调用PutObject操作就会报错:
An error occurred (BadDigest) when calling the PutObject operation (reached max retries: 4): Unknown
相关代码如下:
Django视图代码
from digitalocean_spaces import DigitalOceanSpaces from helpers import resize_maintain_its_aspect_ratio def images_view(request): if request.method == "POST": images = request.FILES.getlist('images') for index, image in enumerate(images): size = image.size content_type = image.content_type file_name = image.name # TODO: fix method # image = resize_maintain_its_aspect_ratio(image, 500) DigitalOceanSpaces().upload_file( key=key, file=image, content_type=content_type, acl='private' )
DigitalOceanSpaces上传方法代码
class DigitalOceanSpaces: def default_session_client(self): session = boto3.session.Session() client = session.client( 's3', region_name=REGION_NAME, endpoint_url=ENDPOINT_URL, aws_access_key_id=ACCESS_KEY_ID, aws_secret_access_key=ACCESS_SECRET_KEY ) return client def upload_file(self, key, file, content_type, acl='private'): client = self.default_session_client() client.put_object( Bucket=BUCKET_NAME, Key=key, Body=file, ACL=acl, ContentType=content_type, Metadata={ 'x-amz-meta-my-key': '*****' } )
图片调整方法代码
from PIL import Image def resize_maintain_its_aspect_ratio(image, base_width): pillow_image = Image.open(image) width_percent = (base_width / float(pillow_image.size[0])) height_size = int((float(pillow_image.size[1]) * float(width_percent))) resized_image = pillow_image.resize((base_width, height_size), Image.ANTIALIAS) return resized_image
原因分析
- 文件指针偏移:
Image.open(image)会读取Django上传的文件对象(InMemoryUploadedFile或TemporaryUploadedFile),读取完成后文件指针会停在文件末尾。后续put_object从当前指针位置读取内容时,实际读到的是空数据,导致计算出的文件摘要与发送内容不匹配,触发BadDigest错误。 - 对象类型不兼容:
resize_maintain_its_aspect_ratio返回的是PIL的Image对象,而put_object的Body参数要求传入类文件对象(支持read()方法)。直接传入PIL Image对象会导致数据格式错误,同样引发摘要不匹配问题。
内容的提问来源于stack exchange,提问作者EdgarAlejandro
相关产品推荐
相关产品推荐

