9

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

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

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

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

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

任何帮助将不胜感激!

概括

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

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

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

4

4 回答 4

12

我在上面的代码中发现了一个缺陷,如果有人想使用它,就会得到“str has no method 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)
于 2012-10-02T23:38:29.910 回答
8

您提到的 SorlImageField只是一个普通的 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)

这意味着您将在磁盘上有两个版本的同一图像 - 一个是 django 图像字段决定保存它(upload_to路径),另一个是 sorl thumbnail 保存了调整大小的缩略图。这与图像被上传和保存两次的事实一起,是这种方法的缺点。虽然实施起来更快

于 2012-02-19T23:29:22.627 回答
2

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

于 2012-09-12T05:29:03.960 回答
0

以下代码使用 PIL 引擎(sorl-thumbnail 的一部分)裁剪名为picture.jpg(使用Python 3.8and测试sorl-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 自第一次提交以来就一直存在,所以在我看来,它在未来不太可能改变:create, cropbox, orientation, flip_dimensions, colorspace, remove_border, calculate_scaling_factor, scale, crop, rounded, blur, padding, write, cleanup, get_image_ratio, get_image_info, get_image, get_image_size, is_valid_image.

于 2020-07-14T21:17:04.817 回答