0

在我的models.py 中,我有一个名为Post 的类和一个名为postcover 的ImageField。我想以 PNG 格式保存每张图像,到目前为止效果很好,但我不知道如何在处理图像后保持实际图像纵横比,因为目前我将其静态转换为 4:3 格式比例,同时将其保存为 500 375 像素。

def save(self, *args, **kwargs):
        super(Post, self).save(*args, **kwargs)
        if self.postcover:
            if os.path.exists(self.postcover.path):
                imageTemproary = Image.open(self.postcover)
                outputIoStream = BytesIO()
                imageTemproaryResized = imageTemproary.resize((500, 375))
                imageTemproaryResized.save(outputIoStream, format='PNG')
                outputIoStream.seek(0)
                self.postcover = InMemoryUploadedFile(outputIoStream, 'ImageField',
                                                  "%s.png" % self.postcover.name.split('.')[0], 'image/png',
                                                  sys.getsizeof(outputIoStream), None)
        super(Post, self).save(*args, **kwargs)

有什么办法可以在保持格式的同时设置最大宽度和高度?

更新:

如果我这样尝试(见下面的帖子):

def save(self, *args, **kwargs):
    super(Post, self).save(*args, **kwargs)
    if self.postcover:
        if os.path.exists(self.postcover.path):
            imageTemproary = Image.open(self.postcover)
            outputIoStream = BytesIO()
            baseheight = 500
            hpercent = (baseheight / float(self.postcover.size[1]))
            wsize = int((float(self.postcover.size[0]) * float(hpercent)))
            imageTemproaryResized = imageTemproary.resize((wsize, baseheight))
            imageTemproaryResized.save(outputIoStream, format='PNG')
            outputIoStream.seek(0)
            self.postcover = InMemoryUploadedFile(outputIoStream, 'ImageField',
                                              "%s.png" % self.postcover.name.split('.')[0], 'image/png',
                                              sys.getsizeof(outputIoStream), None)
    super(Post, self).save(*args, **kwargs)

我只是得到错误:

'int' 对象不可下标

4

2 回答 2

0

也许你可以这样尝试:

image = Image.open(self.postcover)
baseheight = 500
hpercent = (baseheight / float(image.size[1]))
wsize = int((float(image.size[0]) * float(hpercent)))
imageTemproaryResized = image.resize((wsize, baseheight))

如需更多参考,请查看此帖子:https ://ruddra.com/posts/play-with-pillow/#resize-image

于 2019-04-02T10:18:37.010 回答
0

为了更好地理解,我已经在 stackoverflow 上的另一篇文章中讨论了这个问题,使用此解决方案还可以为图像设置固定的基高,如果您使用 PNG 格式,这尤其有用,因为它的大小。如果您使用这种方法使用例如 jpg 格式,则在处理颜色或上传 png 文件的透明背景时会遇到问题,因此请确保您有像这样的propper字段验证器,它只允许上传 jpeg 或只是使用.png...:

验证器.py

def image_file_extension(value):
    ext = os.path.splitext(value.name)[1]  # [0] returns path+filename
    valid_extensions = ['.jpg']
    if not ext.lower() in valid_extensions:
        raise ValidationError(u'Unsupported file extension, allowed is: jpg')

模型.py

   def save(self, *args, **kwargs):
        super(Post, self).save(*args, **kwargs)
        if self.postcover:
            if os.path.exists(self.postcover.path):
                image = Image.open(self.postcover)
                outputIoStream = BytesIO()
                baseheight = 500
                hpercent = baseheight / image.size[1]
                wsize = int(image.size[0] * hpercent)
                imageTemproaryResized = image.resize((wsize, baseheight))
                imageTemproaryResized.save(outputIoStream, format='PNG')
                outputIoStream.seek(0)
                self.postcover = InMemoryUploadedFile(outputIoStream, 'ImageField',
                                                      "%s.png" % self.postcover.name.split('.')[0], 'image/png',
                                                      sys.getsizeof(outputIoStream), None)
        super(Post, self).save(*args, **kwargs)

请记住,您需要两个超级语句,否则这种类型的流程根本无法正常工作。

于 2019-04-06T14:42:35.103 回答