跳转到主要内容

Django模型自动图像处理。

项目描述

Build Status

ImageKit是一个用于处理图像的Django应用。需要缩略图?用户上传图像的黑白版本?ImageKit会为您创建它们。如果您需要从另一张图像程序生成一张图像,您需要ImageKit。

ImageKit附带了一些用于常见任务(如调整大小和裁剪)的图像处理器,但您也可以创建自己的。有关可能性的想法,请查看Instakit项目。

关于ImageKit最新稳定版本的完整文档,请参阅 RTD上的ImageKit

安装

  1. 安装Pillow。(如果你在Django中使用ImageField,你应该已经做了这件事。)

  2. pip install django-imagekit

  3. 'imagekit'添加到你的项目settings.py中的INSTALLED_APPS列表中

使用概述

规格说明

你有一张图片,并想对它进行一些操作以创建另一张图片。但你如何告诉ImageKit要做什么呢?通过定义一个图片规格。

图片规格 是一种 图片生成器,可以从源图片生成新的图片。

在模型中定义规格

使用模型中的ImageSpecField定义图片规格是最简单的方法

from django.db import models
from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFill

class Profile(models.Model):
    avatar = models.ImageField(upload_to='avatars')
    avatar_thumbnail = ImageSpecField(source='avatar',
                                      processors=[ResizeToFill(100, 50)],
                                      format='JPEG',
                                      options={'quality': 60})

profile = Profile.objects.all()[0]
print(profile.avatar_thumbnail.url)    # > /media/CACHE/images/982d5af84cddddfd0fbf70892b4431e4.jpg
print(profile.avatar_thumbnail.width)  # > 100

正如你可能已经注意到的,ImageSpecFields与Django的ImageFields非常相似。区别在于它们是ImageKit根据你提供的说明自动生成的。在上面的例子中,头像缩略图是头像图片的一个缩放版本,以60的质量保存为JPEG。

然而,有时你不需要保留原始图片(如上例中的头像);当用户上传图片时,你只需要处理它并保存结果。在这种情况下,你可以使用ProcessedImageField

from django.db import models
from imagekit.models import ProcessedImageField
from imagekit.processors import ResizeToFill

class Profile(models.Model):
    avatar_thumbnail = ProcessedImageField(upload_to='avatars',
                                           processors=[ResizeToFill(100, 50)],
                                           format='JPEG',
                                           options={'quality': 60})

profile = Profile.objects.all()[0]
print(profile.avatar_thumbnail.url)    # > /media/avatars/MY-avatar.jpg
print(profile.avatar_thumbnail.width)  # > 100

这与我们之前的例子非常相似。我们不再需要指定“源”,因为我们不是处理另一个图片字段,但我们确实需要传递一个“upload_to”参数。这正好与Django ImageFields的行为一致。

在模型外部定义规格

将规格作为模型字段定义是处理图片的一种非常方便的方法,但这并不是唯一的方法。有时你无法(或不想)向模型添加字段,这是完全可以的。你可以定义图片规格类,并直接使用它们。这对于在视图中进行图片处理特别有用——尤其是当处理操作取决于用户输入时。

from imagekit import ImageSpec
from imagekit.processors import ResizeToFill

class Thumbnail(ImageSpec):
    processors = [ResizeToFill(100, 50)]
    format = 'JPEG'
    options = {'quality': 60}

这个类能够以与上面的ImageSpecField完全相同的方式处理图片,可能并不令人惊讶。然而,与图片规格模型字段不同,这个类没有定义规格作用在哪个源上,或者应该对结果执行什么操作;这取决于你。

source_file = open('/path/to/myimage.jpg', 'rb')
image_generator = Thumbnail(source=source_file)
result = image_generator.generate()

调用图片规格上的generate()的结果是一个包含我们已缩放的图片的文件-like对象,你可以用它做任何你想要的事情。例如,如果你想将其保存到磁盘

dest = open('/path/to/dest.jpg', 'wb')
dest.write(result.read())
dest.close()

在模板中使用规格

如果你有一个带有ImageSpecField或ProcessedImageField的模型,你可以轻松地像使用正常的图片字段一样使用这些已处理的图片

<img src="{{ profile.avatar_thumbnail.url }}" />

(这假设你有一个视图,将名为“profile”的上下文变量设置为我们的Profile模型的一个实例。)

但您也可以直接在模板中生成处理后的图像文件——从任何图像开始——而不需要添加任何内容到您的模型中。为了做到这一点,您首先需要在您的应用程序的某个地方定义一个图像生成器类(记住,规范是一种生成器),就像我们在上一节中所做的那样。您还需要一种在模板中引用生成器的方法,所以您需要注册它。

from imagekit import ImageSpec, register
from imagekit.processors import ResizeToFill

class Thumbnail(ImageSpec):
    processors = [ResizeToFill(100, 50)]
    format = 'JPEG'
    options = {'quality': 60}

register.generator('myapp:thumbnail', Thumbnail)

现在我们已经创建了一个图像生成器类,并使用ImageKit注册了它,我们可以在模板中使用它了!

generateimage

ImageKit为您提供的最通用的模板标记称为“generateimage”。它至少需要一个参数:已注册的图像生成器的id。还可以通过关键字样式参数将附加参数传递给已注册的生成器类。正如我们上面所看到的,图像规范构造函数期望一个源关键字参数,因此我们需要传递它来使用我们的缩略图规范。

{% load imagekit %}

{% generateimage 'myapp:thumbnail' source=source_file %}

这将输出以下HTML

<img src="/media/CACHE/images/982d5af84cddddfd0fbf70892b4431e4.jpg" width="100" height="50" />

您还可以添加额外的HTML属性;只需使用两个破折号将它们与关键字参数分开即可。

{% load imagekit %}

{% generateimage 'myapp:thumbnail' source=source_file -- alt="A picture of Me" id="mypicture" %}

没有生成HTML图像标记?没问题。该标记还充当赋值标记,提供对底层文件对象的访问。

{% load imagekit %}

{% generateimage 'myapp:thumbnail' source=source_file as th %}
<a href="{{ th.url }}">Click to download a cool {{ th.width }} x {{ th.height }} image!</a>
thumbnail

因为这是一个非常常见的用例,所以ImageKit还提供了一个“thumbnail”模板标记。

{% load imagekit %}

{% thumbnail '100x50' source_file %}

与上面的generateimage标记一样,thumbnail标记输出一个标记。

<img src="/media/CACHE/images/982d5af84cddddfd0fbf70892b4431e4.jpg" width="100" height="50" />

将此语法与上面的generateimage标记进行比较,您会注意到一些差异。

首先,我们不需要指定图像生成器id;除非我们告诉它否则,thumbnail标记使用id为“imagekit:thumbnail”的生成器。需要注意的是,此标记不使用我们之前定义的Thumbnail规范类;它使用id为“imagekit:thumbnail”的生成器,默认情况下是imagekit.generatorlibrary.Thumbnail

其次,我们传递了两个位置参数(尺寸和源图像),而不是与generateimage标记使用的关键字参数。

与generateimage标记一样,您也可以指定额外的HTML属性用于thumbnail标记,或者将其用作赋值标记。

{% load imagekit %}

{% thumbnail '100x50' source_file -- alt="A picture of Me" id="mypicture" %}
{% thumbnail '100x50' source_file as th %}

在表单中使用规范

除了上面的模型字段外,还有一个ProcessedImageField类的表单字段版本。其功能基本上相同(它处理一次图像并保存结果),但它在表单类中使用。

from django import forms
from imagekit.forms import ProcessedImageField
from imagekit.processors import ResizeToFill

class ProfileForm(forms.Form):
    avatar_thumbnail = ProcessedImageField(spec_id='myapp:profile:avatar_thumbnail',
                                           processors=[ResizeToFill(100, 50)],
                                           format='JPEG',
                                           options={'quality': 60})

使用imagekit.forms.ProcessedImageField(而不是上面的imagekit.models.ProcessedImageField)的好处是,它将创建图像的逻辑保留在模型之外(您会在其中使用正常的Django ImageField)。您甚至可以创建多个表单,每个表单都有自己的ProcessedImageField,并将它们的结果都存储在同一个图像字段中。

处理器

到目前为止,我们只看到了一个处理器:imagekit.processors.ResizeToFill。但ImageKit的功能远不止于调整图像大小,这种功能来自它的处理器。

处理器接受一个PIL图像对象,对其进行操作,并返回一个新的图像对象。一个规范可以使用您想要的任意多个处理器,它们将按顺序运行。

from imagekit import ImageSpec
from imagekit.processors import TrimBorderColor, Adjust

class MySpec(ImageSpec):
    processors = [
        TrimBorderColor(),
        Adjust(contrast=1.2, sharpness=1.1),
    ]
    format = 'JPEG'
    options = {'quality': 60}

《imagekit.processors》模块包含许多常见图像处理的处理器,如缩放、旋转和颜色调整。但是,如果这些处理器无法满足您的需求,您可以创建自己的处理器。您只需定义一个实现process()方法的类即可。

class Watermark(object):
    def process(self, image):
        # Code for adding the watermark goes here.
        return image

这就是全部!要使用您的新自定义处理器,只需将其包含在规格的processors列表中即可。

from imagekit import ImageSpec
from imagekit.processors import TrimBorderColor, Adjust
from myapp.processors import Watermark

class MySpec(ImageSpec):
    processors = [
        TrimBorderColor(),
        Adjust(contrast=1.2, sharpness=1.1),
        Watermark(),
    ]
    format = 'JPEG'
    options = {'quality': 60}

请注意,当您从imagekit.processors导入处理器时,imagekit会反过来从PILKit导入处理器。因此,如果您正在寻找可用的处理器,请查看PILKit。

管理员

ImageKit还包含一个名为imagekit.admin.AdminThumbnail的类,用于在Django管理员更改列表中显示规格(甚至常规ImageFields)。AdminThumbnail用作Django管理员类上的属性

from django.contrib import admin
from imagekit.admin import AdminThumbnail
from .models import Photo

class PhotoAdmin(admin.ModelAdmin):
    list_display = ('__str__', 'admin_thumbnail')
    admin_thumbnail = AdminThumbnail(image_field='thumbnail')

admin.site.register(Photo, PhotoAdmin)

在模型外使用规格

from django.contrib import admin
from imagekit.admin import AdminThumbnail
from imagekit import ImageSpec
from imagekit.processors import ResizeToFill
from imagekit.cachefiles import ImageCacheFile

from .models import Photo

class AdminThumbnailSpec(ImageSpec):
    processors = [ResizeToFill(100, 30)]
    format = 'JPEG'
    options = {'quality': 60 }

def cached_admin_thumb(instance):
    # `image` is the name of the image field on the model
    cached = ImageCacheFile(AdminThumbnailSpec(instance.image))
    # only generates the first time, subsequent calls use cache
    cached.generate()
    return cached

class PhotoAdmin(admin.ModelAdmin):
    list_display = ('__str__', 'admin_thumbnail')
    admin_thumbnail = AdminThumbnail(image_field=cached_admin_thumb)

admin.site.register(Photo, PhotoAdmin)

AdminThumbnail甚至可以使用自定义模板。有关更多信息,请参阅imagekit.admin.AdminThumbnail

管理命令

ImageKit有一个名为generateimages的管理命令,可以为所有注册的图像生成器生成缓存文件。您还可以传递一个生成器ID列表,以便有选择地生成图像。

社区

请使用GitHub问题跟踪器来报告django-imagekit的bug。还存在一个邮件列表,用于讨论项目和提问,以及Freenode上的官方#imagekit频道。

贡献

我们热爱贡献!您不需要是库或Django的专家就可以进行贡献:ImageKit的处理器是独立的类,与Django ORM更令人畏惧的内部结构完全分离。如果您编写了一个可能对其他人有用的处理器,请打开一个pull请求,以便我们可以查看!

您还可以查看我们的开放、贡献友好型问题列表以获取灵感。

有关如何在ImageKit上贡献更多信息,请参阅我们的贡献指南

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定要选择哪个,请了解更多关于安装软件包的信息。

源代码分发

django-imagekit-5.0.0.tar.gz (60.0 kB 查看散列值)

上传时间 源代码

构建分发版

django_imagekit-5.0.0-py3-none-any.whl (39.2 kB 查看散列值)

上传时间 Python 3

由以下支持