【问题标题】:Resizing and updating image in Django在 Django 中调整和更新图像
【发布时间】:2015-03-07 10:37:33
【问题描述】:

我正在覆盖我的保存方法,因为我想调整我的图像大小。我的问题在这段代码中很明显,在我保存数据后发生的事情是 django 启动了一个无限循环。当然是因为我正在检查 self.vertical 是否设置(并且总是设置)。总是调用保存方法。

我可以通过检查我的 self.id 是否为 none 来解决此问题,但代码仅适用于新条目,如果用户尝试更新,则不会发生任何变化,因为 id 不为空。

我还尝试向 kwargs 弹出一个错误参数,保存后设置为 true,但也没有用。有人知道我该如何解决这个问题?

PS:get_thumbnail是sorl缩略图插件的方法。

    def save(self, *args, **kwargs):
        if self.vertical_poster: 
            super(Movie, self).save(*args, **kwargs)

            resized_vertical = get_thumbnail(self.vertical_poster, "155x240", quality=99)            

            #save the new resized file            
            self.vertical_poster.save(resized_vertical.name, ContentFile(resized_vertical.read()), True)

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

任何想法或示例代码将不胜感激!谢谢

【问题讨论】:

    标签: django django-models django-admin sorl-thumbnail


    【解决方案1】:

    您可以检查图像是否已经达到您想要的尺寸。我认为您可以使用https://pypi.python.org/pypi/dimensions 使其变得简单

    def save(self, *args, **kwargs):
        if self.vertical_poster: 
            import dimensions
    
            # Set desired dimensions
            width = 155
            height = 240
    
            image_info = dimensions.dimensions(self.vertical_poster)
    
            if image_info[0] != width and image_info[1] != height:
                dimension = '%dx%d' % (width, height)
                resized_vertical = get_thumbnail(self.vertical_poster, dimension, quality=99)            
    
                #save the new resized file            
                self.vertical_poster.save(resized_vertical.name, ContentFile(resized_vertical.read()), True)
        super(Movie, self).save(*args, **kwargs)
    

    希望对你有帮助。

    【讨论】:

    • 嘿,谢谢你的回答。无论如何,我可以这样做,但 get_thumbnail 不会调整图像的大小。它总是取决于...
    • 我明白了,那么您究竟从哪里获得调整大小的尺寸?
    【解决方案2】:

    如果你使用 ImageField,你可以这样做:

    def save(self, *args, **kwargs):
        if self.vertical_poster.x != 155 or self.vertical_poster.y != 240:
            resized_vertical = get_thumbnail(self.vertical_poster, "155x240", quality=99)            
    
            # save the new resized file            
            self.vertical_poster.save(resized_vertical.name, ContentFile(resized_vertical.read()), True)
    
         super(Movie, self).save(*args, **kwargs)
    

    【讨论】:

    • 嘿,谢谢你的回答。无论如何,我可以这样做,但 get_thumbnail 不会调整图像的大小。它总是取决于...
    【解决方案3】:

    我的解决方案没有覆盖我的保存方法。我做了一些不同的事情:

    我决定使用“django-resized”。该插件兼容“sorl-thumbnail”,并在模型字段上将图像原点调整为指定大小,如下所示:

    from django_resized import ResizedImageField
    
    class Movie(models.Model):
    
        ....
    
        vertical_poster = ResizedImageField(upload_to="movies", width=155, height=240)
    

    我希望这可以帮助其他人。

    链接:https://github.com/un1t/django-resized

    【讨论】:

      【解决方案4】:

      你可以创建一个 mixin 并在任何你想要的地方使用。

      mixins.py

      from io import BytesIO
      from PIL import Image
      
      
      class ShrinkImageMixin:
      
          def shrink_image(self, field_name, resize_shape):
              img: Image = Image.open(getattr(self, field_name))
              img.thumbnail(self.get_shrinked_size(field_name, resize_shape), Image.ANTIALIAS)
              image_file = BytesIO()
              img.save(image_file, 'jpg')
              getattr(self, field_name).file = image_file
      
          def get_shrinked_size(self, field_name, resize_shape):
              actual_img_width, actual_img_height = getattr(self, field_name).width, getattr(self, field_name).height
              ratio = min(resize_shape[0] / actual_img_width, resize_shape[1] / actual_img_height)
              return int(actual_img_width * ratio), int(actual_img_height * ratio)
      
      

      模型.py

      from .mixins import ShrinkImageMixin
      
      class Article(ShrinkImageMixin, models.Model):
      
          ...
      
          background_image = models.ImageField()
      
          ...
      
          def save(self, *args, **kwargs):
              self.shrink_image('background_image', (750, 375))
              super(Article, self).save()
      

      这会将您的图像缩小到您想要的尺寸,同时保持纵横比。您只需要在模型和 resize_shpe 元组中提供图像字段名称即可。

      【讨论】:

        猜你喜欢
        • 2011-10-24
        • 1970-01-01
        • 1970-01-01
        • 2017-06-26
        • 2018-05-03
        • 1970-01-01
        • 1970-01-01
        • 2015-08-06
        • 2022-01-23
        相关资源
        最近更新 更多