如何使用sorl-thumbnail调整源大小?

时间:2012-02-19 23:08:34

标签: django thumbnails image-resizing sorl-thumbnail

我正在网上搜索我的问题,并且无法找到一个明确的答案者。

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

我遇到几个来源引用使用应该在sorl.thumbnail.fields中可用的ThumbnailField模型字段。请参阅链接here。但是,在我从主干中获取最新的sorl副本时,我没有看到任何ThumbnailField或ImageWithThumbnailsField。我在模型中导入它的尝试失败了。我看到这些参考文献虽然陈旧,但想知道我是否可以用最新的sorl实现相同的目标。

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

BTW,我看到easy_thumbnail提供了这个功能,它接受一个输入参数source_resize。

任何帮助将不胜感激!

概要

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

  1. 如果您的应用不需要,请不要存储用户的巨大原始图片。节省磁盘空间。

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

4 个答案:

答案 0 :(得分:12)

我在上面的代码中发现了一个缺陷,如果有人想使用它,那么“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)

答案 1 :(得分:7)

你提到的Sorl ImageField只是一个普通的Django ImageField,还有管理删除缓存缩略图的好处。初始上传没有进行大小调整 - 您需要通过用于上传的视图手动实现。 The docs show how to go about this。您可以使用low level API examlpes

在该视图中使用sorl 来执行实际的调整大小操作

修改

更快的替代方法是在使用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路径),另一个是sorl缩略图已保存它的已调整大小的缩略图。这与图像上传和保存两次的事实一起,是这种方法的缺点。尽管

实施起来更快

答案 2 :(得分:2)

我一直在寻找解决方案并最终编写了应用django-resized

答案 3 :(得分:0)

以下代码使用PIL引擎(Sulth缩略图的一部分)裁剪称为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_dimensions,{{1 }},colorspaceremove_bordercalculate_scaling_factorscalecroproundedblurpaddingwritecleanupget_image_ratioget_image_infoget_imageget_image_size