【问题标题】:Django converting tiff to jpeg with pillowDjango 用枕头将 tiff 转换为 jpeg
【发布时间】:2018-12-15 08:54:46
【问题描述】:

我正在使用 Python 3 中的 Django,并且我有一个带有 ImageField 的模型,我正在尝试覆盖 .save() 以进行 tiff 到 jpeg 的转换:

from PIL import Image
from io import BytesIO
from django.core.files.base import ContentFile

class MyModel(models.Model):

    image = models.ImageField(upload_to=upload_image_to, editable=True, null=True, blank=True)


    def save(self, *args, **kwargs):
        pil_image_obj = Image.open(self.image)
        new_image_io = BytesIO()
        rgb_pil_image_obj = pil_image_obj.convert("RGB")
        rgb_pil_image_obj.save(new_image_io, quality=90, format='JPEG')

        # temp_name = self.image.name
        # self.image.delete(save=False)

        # self.image.save(
        #     temp_name,
        #     content=ContentFile(new_image_io.getvalue()),
        #     save=False
        # )

        super().save(*args, **kwargs)

但是,这会导致:

tempfile.tif: Cannot read TIFF header.
*** OSError: -2

如果我尝试保存实验但只从磁盘打开 TIFF 文件而不是用 Django InMemoryUploadedFile 输入 PIL.Image,那么一切正常,tiff 将转换为 jpeg。

pil_image_obj.verify() 也不会抛出任何异常。

我正在使用Pillow==5.3.0

可能是什么问题?还有其他方法可以进行这种转换吗?

【问题讨论】:

    标签: python django python-imaging-library tiff libtiff


    【解决方案1】:

    您需要将图像文件的路径传递给Image.open()。目前您正在传递该字段本身。

    pil_image_obj = Image.open(self.image.path)  # Pass the path
    

    【讨论】:

    • 我正在使用 s3 和 django 存储,按照您的建议进行操作会得到*** NotImplementedError: This backend doesn't support absolute paths.。我认为加载 self.image 内存中的内容文件应该可以工作
    • 好吧,我没意识到你在使用 s3
    • 是的,我应该提到这一点。但我仍然想知道为什么 InMempryUploadedFile 会失败,因为它不会引发任何 Pillow 错误,即使是 verify()。除了保存时这个 tiff 标头问题之外,大多数事情似乎都是可能的。我也愿意在上传/保存之前即时转换 tiff 的任何其他想法。