Cropping images is common use case in a Web application. For example, some applications let you upload a picture for profile. In addition, it usually also let you crop image for a better result. But, when dealing with image processing we need to install a few dependencies, both in the front-end and in the back-end Using JavaScript with bootstrap.
In this Blog I will explain how to Upload an image and Crop the image and finally upload it and save in the server/Database

First of all we have to install some more dependencies as we are dealing with image uploading and croping
Installing Extra Dependencies
Within your project directory or virtualenv, install Pillow :
pip install pillow
Background
Create project and app using below commands
django-admin startproject crop
cd crop
python manage.py startapp crop_image
django-admin startproject crop cd crop python manage.py startapp crop_image
Consider the following Model
models.py
from django.db import models class Image(models.Model): file = models.ImageField(upload_to='images') uploaded = models.DateTimeField(auto_now_add=True) def __str__(self): return str(self.pk)
Create a urls.py Under crop_image then Consider below Code
urls.py
from django.contrib import admin from django.urls import path from django.conf import settings from django.conf.urls.static import static from crop_image.views import main_view urlpatterns = [ path('admin/', admin.site.urls), path('', main_view, name="main-view") ] urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Consider below file as forms
forms.py
from django import forms from .models import Image class ImageForm(forms.ModelForm): class Meta: model = Image fields = ('file',)
On rendering above froms we wiil get as below

Consider below views file:
views.py
from django.shortcuts import render from .forms import ImageForm from django.http import JsonResponse def main_view(request): form = ImageForm(request.POST or None, request.FILES or None) if form.is_valid(): form.save() return JsonResponse({'message': 'works'}) context = {'form': form} return render(request, 'templates/main.html', context)
Make Some changes in settings.py file
Add our app in the installed apps block as below
INSTALLED_APPS = [ ... 'crop_image', ... ]
And then add templates and static in settings.py file
TEMPLATES = [ { ... 'DIRS': [BASE_DIR,'templates'], .... }, ] . . . STATIC_URL = 'static/' STATICFILES_DIRS=[BASE_DIR/'static'] MEDIA_URL ='/media/' MEDIA_ROOT =BASE_DIR /'media'
Using Bootstrap 3 in this, so my base template looks like below;
base.html
{% load static %} <!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- favicon --> <link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}"/> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous"> <!-- jquery --> <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> <!-- cropper --> <script src="https://cdnjs.cloudflare.com/ajax/libs/cropper/4.1.0/cropper.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropper/4.1.0/cropper.min.css"> <!-- custom css & js--> <link rel="stylesheet" href={% static 'style.css' %}> <script src={% static 'main.js' %} defer></script> <title>image cropper</title> </head> <body> <div class="container mt-3"> {% block content %} {% endblock content %} </div> </body> </html>
main.html
{% extends 'base.html' %} {% block content %} <div id="alert-box"></div> <div id="image-box" class="mb-3"></div> <form action="" id="image-form"> {% csrf_token %} {{form.as_p}} </form> <button class="btn btn-primary mt-3 not-visible" id="confirm-btn">confirm</button> {% endblock content %}
Image Crop Template
In order to crop the image, we need four pieces of information: X coordinate, Y coordinate, height and width of the cropping box the user will eventually use with in the browser.
We are adding croppinng techniques in main.js Javascript file as below
main.js
console.log('hello world') const alertBox = document.getElementById('alert-box') const imageBox = document.getElementById('image-box') const imageForm = document.getElementById('image-form') const confirmBtn = document.getElementById('confirm-btn') const input = document.getElementById('id_file') const csrf = document.getElementsByName('csrfmiddlewaretoken') input.addEventListener('change', ()=>{ alertBox.innerHTML = "" confirmBtn.classList.remove('not-visible') const img_data = input.files[0] const url = URL.createObjectURL(img_data) imageBox.innerHTML = `<img src="${url}" id="image" width="700px">` var $image = $('#image') console.log($image) $image.cropper({ aspectRatio: 16 / 9, crop: function(event) { console.log(event.detail.x); console.log(event.detail.y); console.log(event.detail.width); console.log(event.detail.height); console.log(event.detail.rotate); console.log(event.detail.scaleX); console.log(event.detail.scaleY); } }); var cropper = $image.data('cropper'); confirmBtn.addEventListener('click', ()=>{ cropper.getCroppedCanvas().toBlob((blob) => { console.log('confirmed') const fd = new FormData(); fd.append('csrfmiddlewaretoken', csrf[0].value) fd.append('file', blob, 'my-image.png'); $.ajax({ type:'POST', url: imageForm.action, enctype: 'multipart/form-data', data: fd, success: function(response){ console.log('success', response) alertBox.innerHTML = `<div class="alert alert-success" role="alert"> Successfully saved and cropped the selected image </div>` }, error: function(error){ console.log('error', error) alertBox.innerHTML = `<div class="alert alert-danger" role="alert"> Ups...something went wrong </div>` }, cache: false, contentType: false, processData: false, }) }) }) })
Example css file below
style.css
.not-visible { display: none; }
Make Sure the Files are under the order
└── crop ├── init .py ├── pycache ├── asgi.py ├── settings.py ├── urls.py └── wsgi.p └── crop_image ├── admin.py ├── models.py ├── forms.py ├── urls.py ├── views.py └── templates ├── main.html ├── base.html └── static ├── main.js ├── style.css ├── db.sqlite3 ├── manage.py
On basis of above configaration the Following output will generate
Volia !.. We are successfully Completed Image Cropping in Django Site….
ThankYou…
GitHub link :> https://github.com/saikumar248/Image_Cropping.git