【问题标题】:Resizing images with django-resized使用 django-resized 调整图像大小
【发布时间】:2021-07-13 10:50:49
【问题描述】:

当图像上传到 AWS S3 时,我使用 django-resized 来减小图像的大小。

当图像宽于其高度时,调整大小可以正常工作。但是,当图像高度大于宽度时,输出图像会旋转 90 度,宽度大于高度。

models.py

from django_resized import ResizedImageField

class Catch(models.Model):
    fish_type = models.CharField("Fish Type", max_length=50, choices=fish_choices, default="Carp")
    catch_id = models.AutoField(primary_key=True)
    weight = models.DecimalField("Weight", max_digits=5, decimal_places=2)
    length = models.DecimalField("Length", max_digits=5, decimal_places=2, blank=True, null=True)
    datetime = models.DateTimeField("Catch Time", auto_now=False, auto_now_add=False)
    image = ResizedImageField(size=[1080, 1350], quality=95, null=True, blank=True, default="default_img.png", upload_to="catch_images/")
    fisherman = models.ForeignKey(Fisherman, on_delete=models.CASCADE)
    trip = models.ForeignKey(Trips, on_delete=models.CASCADE)
    hookbait_name = models.CharField('Csali megnevezése', max_length=120, blank=True, null=True)
    hookbait = models.ForeignKey(HookBait, on_delete=models.SET_NULL, blank=True, null=True)

settings.py

DJANGORESIZED_DEFAULT_KEEP_META = True
DJANGORESIZED_DEFAULT_FORCE_FORMAT = 'JPEG'
DJANGORESIZED_DEFAULT_FORMAT_EXTENSIONS = {'JPEG': ".jpg"}
DJANGORESIZED_DEFAULT_NORMALIZE_ROTATION = True

我只想在保持纵横比的同时缩小图像的大小。

提前感谢您的帮助。

编辑!

我设法自己解决了这个问题。我使用枕头来调整图像大小,但我还必须根据方向标签旋转它们。

正确的代码在这里:

models.py

from PIL import Image, ExifTags
from io import BytesIO
from django.core.files import File

class Catch(models.Model):
    fish_type = models.CharField("Fish Type", max_length=50, choices=fish_choices, default="Carp")
    catch_id = models.AutoField(primary_key=True)
    weight = models.DecimalField("Weight", max_digits=5, decimal_places=2)
    length = models.DecimalField("Length", max_digits=5, decimal_places=2, blank=True, null=True)
    datetime = models.DateTimeField("Catch Time", auto_now=False, auto_now_add=False)
    image = models.ImageField(null=True, blank=True, default="default_img.png", upload_to="catch_images/")
    fisherman = models.ForeignKey(Fisherman, on_delete=models.CASCADE)
    trip = models.ForeignKey(Trips, on_delete=models.CASCADE)
    hookbait_name = models.CharField('Csali megnevezése', max_length=120, blank=True, null=True)
    hookbait = models.ForeignKey(HookBait, on_delete=models.SET_NULL, blank=True, null=True)

    class Meta:
        verbose_name = "Catch"
        verbose_name_plural = "Catches"
    
    def save(self, *args, **kwargs):
        if self.image:
            img = Image.open(BytesIO(self.image.read()))
            
            if hasattr(img, '_getexif'):
                exif = img._getexif()
                if exif:
                    for tag, label in ExifTags.TAGS.items():
                        if label == 'Orientation':
                            orientation = tag
                            break
                    if orientation in exif:
                        if exif[orientation] == 3:
                            img = img.rotate(180, expand=True)
                        elif exif[orientation] == 6:
                            img = img.rotate(270, expand=True)
                        elif exif[orientation] == 8:
                            img = img.rotate(90, expand=True)

            img.thumbnail((1080,1080), Image.ANTIALIAS)
            output = BytesIO()
            img.save(output, format='JPEG', quality=95)
            output.seek(0)
            self.image = File(output, self.image.name) 

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

【问题讨论】:

    标签: django django-models image-resizing


    【解决方案1】:

    您应该为此使用 PIL/pillow。像这样编辑您的模型,所有图像将在保存到数据库之前调整大小。

    你可以这样做:

    from PIL import Image as Img
    import io
    from django.core.files.uploadhandler import InMemoryUploadedFile
    
    class Catch(models.Model):
       #rest fields here
       image=models.ImageField(upload_to='Media/Users')
    
       def save(self):
          if self.image:
              img = Img.open(io.BytesIO(self.image.read()))
              if img.mode != 'RGB':
                  img = img.convert('RGB')
              img.thumbnail((100,100), Img.ANTIALIAS)  #(width,height)
              output = io.BytesIO()
              img.save(output, format='JPEG')
              output.seek(0)
              self.image= InMemoryUploadedFile(output,'ImageField', "%s.jpg" 
                          %self.image.name.split('.')[0], 'image/jpeg',"Content- 
                          Type: charset=utf-8", None)
          super(Catch, self).save()
    

    注意:thumbnail 函数还可以减小图像的大小。在这里,我为输出图像指定了宽度和高度 100px。只需根据您的要求更改元组值(width,height)

    另外,如果您只想调整图像大小,可以使用resize 函数而不是thumbnail

    【讨论】:

    • 谢谢。 AWS S3 有一些东西,因为图像仍然被旋转,但是调整大小在开发中完美地工作。有什么想法吗?
    • 我认为使用 base64 可能是一个不错的选择。在 aws s3 上以 base64 字符串格式保存您的图像。获取图片时,可以直接在html图片src属性中使用base64字符串,也可以在投放前将base64字符串转换为图片。这是一个使用base64的stackoverflow线程stackoverflow.com/questions/8499633/…
    猜你喜欢
    • 1970-01-01
    • 2017-01-01
    • 2017-08-24
    • 2015-01-16
    • 2011-10-24
    • 2013-10-03
    • 2011-02-20
    • 2015-05-02
    • 2011-09-07
    相关资源
    最近更新 更多