【问题标题】:Django Save Image In Different Formats Using PillowDjango 使用 Pillow 以不同格式保存图像
【发布时间】:2023-03-26 09:40:01
【问题描述】:

我正在为我的学校制作这个网站,我需要优化它,就像很多一样。

因此,我决定以 jpeg-2000 和 webp 等下一代格式提供我所有的压缩图像。使用 Pillow,这是我目前所拥有的:

class Bulletin(models.Model):
     banner = models.ImageField(upload_to='banner/', blank=True)

     def save(self, *args, **kwargs):
        super().save()
        if self.banner:
            thumbnail = Image.open(self.banner.path)
            resized = thumbnail.resize((1280, 620))
            resized.save(self.banner.path, quality=60)

所以我认为这会压缩图像(如果我在上面的代码中犯了错误,请告诉我)。

所以现在我希望能够以多种格式保存这张图片 我希望上传的一张图片以这些格式保存:

  • webp
  • jpeg2000
  • JPEG

我正在考虑在我的模型横幅上创建更多字段,例如字段 banner_webp,然后我会将其转换为 webp,并在保存期间将转换后的图像保存到该字段。

问题是我不知道如何使用 Pillow 转换图像,或者如何做我所要求的。感谢您的帮助。

【问题讨论】:

  • 对不起,如果我的赏金不清楚,我想知道如何使用 django 以多种格式保存图像。谢谢。
  • 我认为您没有阅读 Pillow 文档。它具有您提到的两种格式(JPEG 2000 和 WebP),尽管有一些额外的依赖项。 pillow.readthedocs.io/en/stable/handbook/…
  • @Aaqib Bashir,我的问题措辞错误。我想将用户上传的图像转换为 webp、jpeg2000 和 jpeg。我知道 Pillow 具备这两种格式的能力。
  • 带有枕头的“转换”应该只是以新格式加载和保存。看看Image.save():使用扩展名为“jpeg”或“webp”的文件名来调用它就足够了。这是你想要的吗?然后我将其添加为答案。

标签: django image format python-imaging-library


【解决方案1】:

John 已经找到了可行的解决方案。我建议对此进行以下更改:

  • 假设公告有更多字段可能会在不更改横幅的情况下发生更改:您不需要在公告的每个save() 上重新编码图像。如果您将编码放入其自己的函数中,则可以在上传视图中专门调用该函数,如果这是您的代码中修改此值的唯一位置。 There are possibilitiessave() 中检测该字段是否已更改,因此这也是一个选项。
  • 如果您保留自定义save() 方法:您应该在super 调用中传递参数:super().save(*args, **kwargs)
  • 您无需删除旧扩展名:您可以将图像命名为“whatever.jpg.webp”。它不会混淆计算机,而且我认为这个名称非常清楚地表明它是对原始文件的重新编码。此外,这允许您保持原始文件原样,以防有一天您决定要使用其他参数对图像进行编码,例如具有不同的质量设置。
  • 对重新编码的图像文件路径使用统一的访问器可以防止一些与拼写错误相关的错误。
class Bulletin(models.Model):
    BANNER_REENCODE_FORMATS = ["jpg", "jp2", "webp"]
    banner = models.ImageField(upload_to='banner/', blank=True)

    def reencoded_banner_path(self, file_format="jpg"):
        assert file_format in self.BANNER_REENCODE_FORMATS
        return self.banner.path + "." + file_format

    def reencode_banner(self):
        image = Image.open(self.banner.path).convert("RGB").resize((1280, 620))
        for extension in self.BANNER_REENCODE_FORMATS:
            image.save(self.reencoded_banner_path(extension), quality=60)

带有以下模板标签:

@register.filter(name='reencoded_banner_path')
@stringfilter
def reencoded_banner_path(bulletin, format):
    return bulletin.reencoded_banner_path(format)

你可以在你的模板中使用它:

{{ bulletin|reencoded_banner_path:"webp" }}

请注意,您可能希望在图像上传时有一些重命名逻辑,以便在用户上传两个具有相同文件名的文件时不会中断。

【讨论】:

  • 哦,好的,谢谢!同样在重命名逻辑部分,是的,我已经设置了一些逻辑。
  • 大家好。我试试这个,但我需要你提到的重命名逻辑方面的帮助。
  • 我认为最好为此提出一个新问题
猜你喜欢
  • 1970-01-01
  • 2019-01-30
  • 2012-11-18
  • 2015-10-24
  • 1970-01-01
  • 2021-09-04
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多