如何使用 sorl 缩略图调整源的大小



我在网上搜索我的问题,找不到明确的答案或任何例子。

基本上,我想使用 sorl 并希望在模型期间调整源图像的大小,以将其大小调整为 640x480 大小,这样我就不会最终将用户的原始 2.5 MB 文件存储在磁盘上。然后,我将使用模板标签从我的源代码中创建常规缩略图,如 sorl 中所述。

我遇到了几个来源引用使用缩略图字段模型字段,该字段应该在sorl.thumbnail.fields中可用。请参阅此处的链接。但是,在我从主干中获取的最新 sorl 副本中,我没有看到任何缩略图字段或带有缩略图字段的图像。我尝试将其导入模型会相应地失败。我看到这些参考资料很旧,想知道我是否可以使用最新的 sorl 实现相同的效果。

另一方面,sorl 文档仅指示来自 sorl.thumbnail 的 ImageField(请参阅此处(,它没有任何大小参数来控制源大小调整。

顺便说一句,我看到此功能可用于source_resize输入参数的easy_thumbnail。

任何帮助将不胜感激!

总结

我接受了下面的答案,但是我觉得对这个用例的自然 sorl 支持非常有用 - 即将resize_source参数添加到 sorl 的 ImageField 以允许调整源图像的大小。以下是为什么这在该领域有用的两个因素:

  1. 如果您的应用程序不需要它,则不要存储用户的巨大原始图像。节省磁盘空间。

  2. 如果您没有特定的极端高质量原因,请不要花费额外的 CPU 来调整来自巨大源图像的缩略图大小。为了避免这种情况,可以在模板中将嵌套标签写入较小尺寸图像的缩略图,但它很快就会变得烦人。

我在上面的代码中发现了一个缺陷,如果有人想使用它,得到"str 没有方法 chunck(("。这是我的解决方法:

    from sorl.thumbnail import get_thumbnail
    from django.core.files.base import ContentFile
 class Foo(models.Model):
    image = models.ImageField(upload_to...)

    def save(self, *args, **kwargs):
        if not self.id:  
            super(Foo, self).save(*args, **kwargs)  
            resized = get_thumbnail(self.image, "100x100" ...)
            self.image.save(resized.name, ContentFile(resized.read()), True)
        super(Foo, self).save(*args, **kwargs)

提到的Sorl ImageField只是一个普通的Django ImageField,具有管理缓存缩略图删除的额外好处。初始上传时无需调整大小 - 这是您必须通过用于上传的视图手动实现的内容。文档展示了如何执行此操作。您可以在该视图中使用 sorl 来执行实际的大小调整操作本身,使用低级 API 检查

编辑

更快的替代方法是在使用 sorl 保存模型时调整图像大小。您可以执行以下操作(尽管完全未经测试!

from sorl.thumbnail import get_thumbnail
class Foo(models.Model):
    image = models.ImageField(upload_to...)
    def save(self, *args, **kwargs):
        if not self.id:
            # Have to save the image (and imagefield) first
            super(Foo, self).save(*args, **kwargs)
            # obj is being created for the first time - resize
            resized = get_thumbnail(self.image, "100x100" ...)
            # Manually reassign the resized image to the image field
            self.image.save(resized.name, resized.read(), True)
        super(Foo, self).save(*args, **kwargs)

这意味着磁盘上将有 2 个版本的同一图像 - 一个是 Django 图像字段决定保存它(upload_to路径(,另一个是 Sorr 缩略图保存其调整大小的缩略图。这一点,以及图像上传和保存两次的事实,是这种方法的缺点。虽然实施起来更快

我一直在寻找解决方案一段时间,最终编写了应用程序 django ressize。

以下代码使用 PIL 引擎(sorl-thumbnail 的一部分(裁剪名为 picture.jpg 的图像(使用 Python 3.8sorl-thumbnail==12.6.3 进行测试(:

#
# Change this import to get the Engine of your underlying libraries.
# Options are: convert_engine, pgmagick_engine, pil_engine, vipsthumbnail_engine or wand_engine.
#
from sorl.thumbnail.engines.pil_engine import Engine
# This object has all we need
engine = Engine()
#
# When receiving data from a request
# you probably have a BytesIO instance ready to use like:
#
#   im = engine.get_image(my_bytes_io)
#
with open("picture.jpg", "rb") as f:
    im = engine.get_image(f)
im_crop = engine.crop(im, (535, 535), options={'crop': 'smart'})
im_crop.save("picture-thumb.jpg")

我不会修改 save 方法,而是有一个用于减小图像大小的辅助函数(使用上面的行(,并在更新图像字段之前从 Django 视图或表单调用它。尽管它可以在save本身上工作。

另一方面,引擎 API 具有更多有用的功能,这些功能可能很有用!这个 API 自第一次提交以来就已经存在,所以在我看来,将来不太可能改变:createcropboxorientationflip_dimensionscolorspaceremove_bordercalculate_scaling_factorscalecroproundedblurpaddingwritecleanupget_image_ratioget_image_infoget_imageget_image_sizeis_valid_image .

最新更新