You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 18:57:43