在 Python 中上传到 S3 之前从图像中删除 EXIF

Remove EXIF from Image Before Upload to S3 in Python

我想在上传到 s3 之前从图像中删除 exif。我发现了一个类似的问题(here), but it saves as a new file (I don't want it). Then I found an another way (here),然后我尝试实现它,测试时一切正常。但在我部署到 prod 后,一些用户反映他们 偶尔 在上传大小为 1 MB 及以上的图像时遇到问题,所以他们必须尝试几次。

所以,我只想确定我的代码是否正确?或者我可以改进一些地方。

from PIL import Image

# I got body from http Request
img = Image.open(body)

img_format = img.format

# Save it in-memory to remove EXIF
temp = io.BytesIO()
img.save(temp, format=img_format)
body = io.BytesIO(temp.getvalue())

# Upload to s3
s3_client.upload_fileobj(body, BUCKET_NAME, file_key)

*我还在查明这个问题是否是由其他原因引起的。

您应该能够将像素数据和调色板(如果有)从现有图像复制到新的剥离图像,如下所示:

from PIL import Image

# Load existing image
existing = Image.open(...)

# Create new empty image, same size and mode
stripped = Image.new(existing.mode, existing.size)

# Copy pixels, but not metadata, across
stripped.putdata(existing.getdata())

# Copy palette across, if any
if 'P' in existing.mode: stripped.putpalette(existing.getpalette())

请注意,这将从您的图像中删除所有元数据...EXIF、评论、IPTC、8BIM、ICC 颜色配置文件、dpi、版权、是否是渐进式、是否是动画。

另请注意,当您保存它时,它会写入 PIL 默认质量为 75 的 JPEG 图像,这可能与您的原始图像相同也可能不同 - 即尺寸可能会改变。


如果上面的剥离过多,你可以像这样剥离EXIF:

from PIL import Image

im = Image.open(...)

# Strip just EXIF data
if 'exif' in im.info: del im.info['exif']

保存时,您可以测试是否为 JPEG,并通过以下方式传播现有质量:

im.save(..., quality='keep')

注意:如果您想验证任何给定图像中的元数据,在剥离前后,您可以在 macOS 上使用 exiftoolImageMagick,Linux和Windows,如下:

exiftool SOMEIMAGE.JPG

magick identify -verbose SOMEIMAGE.JPG