Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Django에서 클라이언트 측 이미지 크롭·회전·확대/축소 구현하기

웹 서비스를 개발하다 보면 사용자가 업로드한 이미지를 회전하거나 확대·축소해야 하는 경우가 자주 발생합니다. 이럴 때 클라이언트 측 이미지 편집 라이브러리를 활용하면 별도의 서버 처리 없이 브라우저에서 바로 이미지를 조작할 수 있습니다. 이 글에서는 Django 프로젝트에 django-client-side-image-cropping 라이브러리를 적용해 이미지 크롭(자르기), 회전, 확대/축소 기능을 구현하는 방법을 단계별로 살펴보겠습니다.

사전 준비

먼저 Django 프로젝트와 앱을 생성하고, URL을 설정하는 등 기본적인 환경을 구성합니다. 이때 생성한 앱은 반드시 settings.py의 INSTALLED_APPS에 추가해야 합니다.

그다음 아래 명령어로 이미지 크로핑 라이브러리를 설치합니다.

pip install django-client-side-image-cropping

설치가 완료되면 settings.py의 INSTALLED_APPS에 다음 한 줄을 추가합니다.

INSTALLED_APPS += ['client_side_image_cropping']

지금까지는 새로 설치한 모듈을 앱으로 등록하는 간단한 설정 작업입니다.

예제 코드

1. models.py — 모델 정의

from django.db import models

# Create your models here.
class Data(models.Model):
    image = models.ImageField(upload_to='myimages/')

여기서는 이미지 필드 하나를 가진 간단한 모델을 정의했습니다. 업로드된 파일은 myimages/ 디렉터리에 저장됩니다.

2. 미디어 설정

업로드된 이미지를 저장하고 불러올 수 있도록 settings.py에 MEDIA_ROOT와 MEDIA_URL을 설정합니다.

3. urls.py — URL 및 미디어 경로 설정

from django.urls import path
from . import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('', views.home, name="home"),
]
urlpatterns += static(settings.MEDIA_URL,
                      document_root=settings.MEDIA_ROOT)

기본 페이지 라우팅과 함께 개발 환경에서 미디어 파일을 서빙하기 위한 media url 설정도 추가했습니다.

4. views.py — 폼과 크로핑 위젯 적용

from django.shortcuts import render
from django import forms
from .models import Data
from client_side_image_cropping import ClientsideCroppingWidget

# Create your views here.
class DataForm(forms.ModelForm):
    class Meta:
        model = Data
        fields = "__all__"
        widgets = {
            'image': ClientsideCroppingWidget(
                width=400,
                height=600,
                preview_width=100,
                preview_height=150,
            )
        }

def home(request):
    if request.method == "POST":
        form = DataForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
    form = DataForm()
    return render(request, 'home.html', {"form": form})

모델 폼(ModelForm)을 기반으로 간단한 입력 폼을 만들고, image 필드에 크로핑 위젯(ClientsideCroppingWidget)을 연결했습니다. width와 height는 최종 저장될 이미지 비율을, preview_width와 preview_height는 화면에 표시되는 미리보기 크기를 결정합니다.

5. home.html — 템플릿 작성

{% load static %}
{% load cropping %}
{% load thumbnail %}
<!DOCTYPE html>
<html>
    <head>
        <title>TUT</title>
        <link rel="stylesheet" href="{% static "client_side_image_cropping/cropping.css" %}">
        <link rel="stylesheet" href="{% static "client_side_image_cropping/cropping_widget.css" %}">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script src="{% static "client_side_image_cropping/croppie.min.js" %}"></script>
        <script src="{% static "client_side_image_cropping/cropping_widget.js" %}"></script>
    </head>
    <body>
        <h2>HI</h2>
        <form method="post" enctype="multipart/form-data">
            {% csrf_token %}
            {{ form.as_p }}
            <input type="submit" value="Save"/>
        </form>
    </body>
</html>

프런트엔드에서는 jQuery와 라이브러리에서 제공하는 CSS·JS 파일들을 로드하고, 이미지 입력을 받는 폼을 렌더링합니다. 특히 파일 업로드를 위해 form 태그에 enctype="multipart/form-data" 속성을 반드시 지정해야 한다는 점에 유의하세요.

실행 결과

모든 설정이 끝났습니다. 서버를 실행하면 아래와 같은 인터페이스가 나타나며, 여기서 사진을 자유롭게 회전하거나 확대·축소할 수 있습니다.

Django에서 클라이언트 측 이미지 크롭·회전·확대/축소 구현하기Django에서 클라이언트 측 이미지 크롭·회전·확대/축소 구현하기

기본 UI는 다소 투박하지만 CSS를 활용하면 충분히 세련되게 개선할 수 있습니다. 또한 업로드된 이미지가 어긋나 보일 수 있는데, 이는 브라우저 문제로 인한 것일 수 있으므로 회전 기능을 사용해 위치를 맞춰 주면 됩니다.