GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

matthewwithanm

django-imagekit – Djangoの自動画像処理。 現在v4.0

投稿日:

Djangoの自動画像処理。 現在v4.0 http://django-imagekit.rtfd.org/

ImageKitは画像を処理するDjangoアプリです。 サムネイルが必要ですか? ユーザーがアップロードした画像の白黒バージョンですか? ImageKitはあなたのためにそれらを作るでしょう。 プログラム的に別のイメージを生成する必要がある場合は、ImageKitが必要です。

ImageKitには、サイズ変更やトリミングなどの一般的なタスク用の画像プロセッサが付属していますが、自分で作成することもできます。 可能であれば、 Instakitプロジェクトをチェックしてください

最新の安定版ImageKitに関する完全なドキュメントは、 ImageKit on RTDを 参照してください

インストール

  1. PILまたはピロー取り付けます。 (もしあなたがDjangoでImageFieldを使用しているのであれば、すでにこれを行っているはずです。)
  2. pip install django-imagekit
  3. あなたのプロジェクトのsettings.pyのINSTALLED_APPSリストに'imagekit'を追加してください

注意

これまでにPillowを見たことがない人は、setuptoolsと互換性のあるPILのより頻繁にアップデートされた「フレンドリーな」フォークと考えています。 そのため、PILと同じ名前空間を共有し、ドロップイン置換になります。

使用法の概要

仕様

1つのイメージがあり、別のイメージを作成するために何かをしたいとします。 しかし、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とまったく同じように動作します。

注意

ImageSpecFieldの “upload_to”引数が必要ない理由が不思議に思われるかもしれません。 その理由は、ProcessedImageFieldsは実際にはImageFieldと似ています。データベースにファイルパスを保存し、モデルに追加するときにsyncdbを実行する(または移行を作成する)必要があるからです。

一方、ImageSpecFieldsは仮想です。データベースにフィールドを追加せず、データベースを必要としません。 これは多くの理由で便利ですが、イメージファイルへのパスをソースイメージと仕様に基づいてプログラムで構築する必要があることを意味します。

モデル外の仕様の定義

仕様をモデルフィールドとして定義することは、画像を処理するのに非常に便利な方法の1つですが、唯一の方法ではありません。 場合によっては、モデルにフィールドを追加できない(またはしたくない)こともあります。これは問題ありません。 イメージ仕様クラスを定義して直接使用することができます。 これは、特に処理が実行されているときに、ユーザー入力に依存するビューで画像処理を行う場合に特に便利です。

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()

注意

あなたはopenを使う必要はありません! モデルのImageFieldを含め、任意のFile-likeオブジェクトを使用できます。

画像仕様でgenerate()を呼び出した結果は、サイズ変更された画像を含むファイルのようなオブジェクトであり、必要なものは何でもできます。 たとえば、ディスクに保存する場合は次のようにします。

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)

注意

ジェネレータを任意のIDで登録できますが、賢明に選択してください! あまりにも一般的なものを選択すると、使用している別のサードパーティのアプリと競合する可能性があります。 このため、ジェネレータIDの前にアプリケーションの名前を付けることをお勧めします。 また、ImageKitは、パターンマッチングを行う際にコロンをセパレータとして認識します(例えば、generateimages管理コマンドのように)ので、それらも使用することをお勧めします!

警告

このコードは、あなたが望む任意のファイルに入れることができますが、ロードされていることを確認する必要があります! 簡単にするために、ImageKitは、インストールされている各アプリケーションで「imagegenerators」という名前のモジュールを自動的に読み込もうとします。 だから、頭痛を救ってイメージのスペックをそこに入れてみませんか?

Image Generatorクラスを作成し、ImageKitで登録したので、テンプレートで使用することができます。

イメージを生成する

ImageKitが提供する最も一般的なテンプレートタグは、 “generateimage”と呼ばれます。 少なくとも1つの引数、登録されたイメージジェネレータのIDが必要です。 追加のキーワードスタイルの引数は、登録されたジェネレータクラスに渡されます。 上で見たように、画像スペックコンストラクタはソースキーワード引数を期待しているので、サムネイル仕様を使用するために渡す必要があります。

{% load imagekit %}

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

これは次のHTMLを出力します:

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

HTML属性を追加することもできます。 2つのダッシュを使用してキーワードargsからそれらを分けるだけです:

{% 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>

サムネイル

このような一般的な使用例であるため、ImageKitは「サムネイル」テンプレートタグも提供しています。

{% load imagekit %}

{% thumbnail '100x50' source_file %}

generateimageタグと同様に、サムネイルタグは<img>タグを出力します。

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

このシンタックスを上記のgenerateimageタグと比較すると、いくつかの違いがあります。

まず、画像生成プログラムIDを指定する必要はありませんでした。 それ以外のことを言わない限り、サムネイルタグはid “imagekit:thumbnail”で登録されたジェネレータを使用します。 このタグは、前に定義したThumbnailスペッククラスを使用していないことに注意してください これはid “imagekit:thumbnail”で登録されたジェネレータを使用しています。デフォルトではimagekit.generatorlibrary.Thumbnailです。

次に、generateimageタグで使用したキーワード引数とは対照的に、2つの位置引数(ディメンションとソースイメージ)を渡します。

generateimageタグと同様に、サムネイルタグに追加のHTML属性を指定することも、割り当てタグとして使用することもできます。

{% 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 1つのプロセッサしか見ていません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リストにそのカスタムプロセッサを含めるだけ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.processorsはPILKitからプロセッサをインポートします。 したがって、使用可能なプロセッサーを探している場合は、PILKitを見てください。

管理者

ImageKitには、 Djangoの管理者変更リストに仕様(または通常のImageField)を表示するためのimagekit.admin.AdminThumbnailという名前のクラスも含まれています 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には、登録されたすべてのイメージジェネレータのキャッシュファイルを生成する1つの管理コマンド-imageimagesがあります。 画像を選択的に生成するために、ジェネレータIDのリストを渡すこともできます。

コミュニティ

django-imagekitのバグを報告するには、GitHubのissueトラッカーを使用してください。 プロジェクトを議論し質問をするメーリングリスト 、Freenodeの公式の#imagekitチャンネルもあります。

貢献する

寄付が大好き! また、ライブラリやDjangoの専門家でなくても、ImageKitのプロセッサは、DjangoのORMのより威圧的な内部とは完全に別個の独立したクラスです。 他の人に役立つと思われるプロセッサを作成した場合は、プルリクエストを開いてみてください。

また、貢献しやすいオープンなアイディアのリストもご覧ください。

ImageKitを使った投球の詳細については、 寄稿のガイドラインをご覧ください。







-matthewwithanm

執筆者: