【问题标题】:How to resize uploaded file with PIL before saving it?如何在保存之前使用 PIL 调整上传文件的大小?
【发布时间】:2014-04-19 10:08:58
【问题描述】:

我意识到这是一项微不足道的任务,而且这个问题被多次回答,但我就是无法理解。有没有办法在将图像保存到磁盘之前调整大小和裁剪图像?我发现的所有解决方案都倾向于存储图像,调整大小,然后再次存储。我可以这样做吗?

# extending form's save() method
def save(self):
    import Image as pil

    # if avatar is uploaded, we need to scale it
    if self.files['avatar']:
        img = pil.open(self.files['avatar'])
        img.thumbnail((150, 150), pil.ANTIALIAS)

        # ???
        # self.files['avatar'] is InMemoryUpladedFile
        # how do I replace self.files['avatar'] with my new scaled image here?
        # ???

    super(UserForm, self).save()

【问题讨论】:

    标签: python django python-imaging-library


    【解决方案1】:

    我能够弄清楚这一点。您只需将修改后的文件保存为StringIO,然后从中创建一个新的InMemoryUploadedFile。这是完整的解决方案:

    def save(self):
    
        import Image as pil
        import StringIO, time, os.path
        from django.core.files.uploadedfile import InMemoryUploadedFile
    
        # if avatar is uploaded, we need to scale it
        if self.files['avatar']:
            # opening file as PIL instance
            img = pil.open(self.files['avatar'])
    
            # modifying it
            img.thumbnail((150, 150), pil.ANTIALIAS)
    
            # saving it to memory
            thumb_io = StringIO.StringIO()
            img.save(thumb_io,  self.files['avatar'].content_type.split('/')[-1].upper())
    
            # generating name for the new file
            new_file_name = str(self.instance.id) +'_avatar_' +\
                            str(int(time.time())) + \
                            os.path.splitext(self.instance.avatar.name)[1]
    
            # creating new InMemoryUploadedFile() based on the modified file
            file = InMemoryUploadedFile(thumb_io,
                                        u"avatar", # important to specify field name here
                                        new_file_name,
                                        self.files['avatar'].content_type,
                                        thumb_io.len,
                                        None)
    
            # and finally, replacing original InMemoryUploadedFile() with modified one
            self.instance.avatar = file
    
        # now, when form will be saved, it will use the modified file, instead of the original
        super(UserForm, self).save()
    

    【讨论】:

      【解决方案2】:

      我不熟悉 PIL,但正如我从文档中看到的,您可以将文件对象作为“文件”参数传递给“打开”函数。

      Django request.FILES 存储 UploadedFile 对象 - 上传文件的简单包装器(存储在内存中或临时文件中),它支持读取、查找和告诉操作,因此可以直接传递给 PIL“打开”函数。

      【讨论】:

        猜你喜欢
        • 2011-12-19
        • 2012-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-16
        • 1970-01-01
        • 1970-01-01
        • 2015-07-24
        相关资源
        最近更新 更多