この記事では、Djangoで画像をグレー変換するwebアプリを作ってみたので紹介します。

ネットとかを調べると、画像をアップロードしてテンプレートに表示する方法とかはあるんですが、アップした画像を画像処理する方法があんまり無いような感じだったので紹介します。
画像処理にはopencvと言うライブラリを使っています。グレースケールだけでなく様々な画像処理ができる強力なライブラリです。
実行環境
・Python 3.6
・Django 2.1
目次
使用するライブラリ
pillowはImageFileldを使うためのライブラリ、opencv-pythonはpythonでopencvを使うためのライブラリです。両方ともpipでインストールできますのでしておきましょう。
pip install pillow pip install opencv-python
モデル
画像はImageFieldを使って管理します。
models.py
from django.db import models class Document(models.Model): description = models.CharField(max_length=255, blank=True) photo = models.ImageField(upload_to='gallery/', default='SOME STRING') uploaded_at = models.DateTimeField(auto_now_add=True) gray = models.ImageField(default='Not Set')
変換前の画像も残しておきたいので、元画像をphoto, グレー画像をgrayと言う名前で2種類のフィールドを宣言しておきます。
photoの方はユーザがブラウザからアップロード、grayはボタンが押されたらビュー内で画像処理して自動的に保存するように作りたいと思います。
アップロード機能の作り方は以下の記事にそれぞれまとめてあります。
https://ymgsapo.com/file-upload/
モデルを作成したら、以下のコマンドでマイグレーションします。
python manage.py makemigrations your_app_name python manage.py migrate
ビュー
views.py
from django.shortcuts import render, redirect from .forms import DocumentForm from .models import Document import cv2 from django.conf import settings def edit(request, num): obj = Document.objects.get(id=num) if request.method == 'POST': if 'button_gray' in request.POST: gray(obj.photo.url) obj.gray = "gallery/gray.jpg" obj.save() return redirect('edit', num) params = {'data': obj} return render(request, 'edit.html', params) def gray(url): path = settings.BASE_DIR + url print(path) img = cv2.imread(path) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) output = settings.BASE_DIR + "/media/gallery/gray.jpg" cv2.imwrite(output, img_gray)
主な処理は以下の通り。
- ボタンが押されたら、元画像の保存場所を取得する
- gray関数内で元画像を読み込み、グレースケール変換する
- “gray.jpg”と言う名前でグレー画像を保存する
- グレー画像の場所を指定、save()でレコードの更新を行う
opencvの関数で画像を読み込んでグレースケール処理した後に、CRUDの1つである「レコードの更新」を行っています。
プロジェクトのルートパスはsettings.pyをインポートして、その中のBASE_URLを使っています。
なお、今回はグレー画像の名前を「gray.jpg」と固定していますが、本当はアップロードした「元画像の名前_gray.jpg」とかにした方が良いです。他のアップした画像と被ってしまいますので。
テンプレート
edit.html
<body> <img src="{{ data.photo.url }}" width="10%" height="10%"/> <form action="{% url 'edit' data.id %}" method="post"> {% csrf_token %} <input type="submit" name="button_gray" value="gray"> </form> <img src="{{ data.gray.url }}" width="10%" height="10%"/> </body>
imgタグで画像を表示するようにしています。サイズを縦横10%に縮小しています。