【问题标题】:How to convert an image to a specific file size?如何将图像转换为特定的文件大小?
【发布时间】:2016-07-20 03:15:47
【问题描述】:

我正在与PillowDjangodjango-imagekit 合作。

我希望能够拥有一个个人资料图片模型字段(可能使用 imagekit 中的 ProcessedImageField 类),它将拍摄任何图像,转换为 JPEG,将其裁剪为 150x150,并使其文件大小为 5KB。

前两个很简单:

profile_picture = imagekit.models.ProcessedImageField(upload_to=get_profile_picture_file_path,
                                                      format='JPEG',
                                                      processors=[ResizeToFill(height=150, width=150)]
                                                      )

但是如何确保文件大小为 5KB?我可以在ProcessedImageField 中使用类似options={'quality': 60} 参数的东西,但这似乎只与原始文件大小有关(据我所知)。

解决方案不必使用 django-imagekit,但这是首选。

【问题讨论】:

    标签: python django image pillow django-imagekit


    【解决方案1】:

    也许是这样。上传后检查图像的大小并在覆盖的save方法中将其删除或减小更多:

    class Images(models.Model):
        profile_picture = imagekit.models.ProcessedImageField(upload_to=get_profile_picture_file_path,
                                                      format='JPEG',
                                                      processors=[ResizeToFill(height=150, width=150)]
                                                      )
    
        def save(self, force_insert=False, force_update=False, using=None,
                 update_fields=None):
    
            if os.stat(get_profile_picture_file_path + "/" + self.profile_picture.new_name).st_size > max_size:
                do_something_further_image_processing_to_decrease_size
    
            super(Images, self).save()
    

    【讨论】:

    • 这是验证文件是否太大的良好开端,但do_something_further_image_processing_to_decrease_size 中的逻辑确实是问题的相关部分。您如何确保每次都将文件大小减小到特定大小(即使是不同分辨率/JPEG 质量的图像)?
    • 我可能会在此处添加迭代函数,该函数将分辨率降低 10% 或其他与每次迭代生成图片的当前大小相对应的因素。 PIL给了你这样的可能。
    【解决方案2】:

    我曾经遇到过类似的问题,所以我决定在使用信号保存模型后使用从 django 调用的 OS 工具(jpegoptim、optipng 等)优化图像(您也可以使用覆盖保存方法)。此工具可优化和消除图像中的元数据。另一方面,您可以研究 150x150 的 jpg 文件的平均压缩比和大小,并尝试猜测最佳质量来设置检查:(jpeg compression ratio)

    这是我保存后优化文件的代码,我正在使用简单的缩略图库,它在保存后为我提供信号:

    @receiver(saved_file)
    def optimize_file(sender, fieldfile, **kwargs):
        optimize(fieldfile.path)
    
    
    # thumbnail optimization
    @receiver(thumbnail_created)
    def optimize_thumbnail(sender, **kwargs):
        optimize(sender.path)
    
    def optimize(path):
        """
        install image utilities
        apt-get install jpegoptim optipng pngcrush advancecomp
        :param path:
        :return:
        """
        # taken from trimage (http://trimage.org/)
        runString = {
            ".jpeg": u"jpegoptim -f --strip-all '%(file)s' ; chmod 644 '%(file)s'",
            ".jpg": u"jpegoptim -f --strip-all '%(file)s' ; chmod 644 '%(file)s'",
            ".png": u"optipng -force -o7 '%(file)s' && advpng -z4 '%(file)s' && pngcrush -rem gAMA -rem alla -rem cHRM -rem iCCP -rem sRGB -rem time '%(file)s' '%(file)s.bak' && mv '%(file)s.bak' '%(file)s' ; chmod 644 '%(file)s'"
        }
    
        ext = splitext(path)[1].lower()
        if ext in runString:
            subprocess.Popen(runString[ext] % {'file': path}, shell=True)
    

    【讨论】:

      猜你喜欢
      • 2017-06-24
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      • 2017-09-22
      • 2021-10-15
      • 2023-03-30
      • 2011-05-14
      相关资源
      最近更新 更多