Package: django-image-cropping
django-image-cropping is an app for cropping uploaded images via Django’s admin backend usingJcrop.Screenshot:django-image-cropping is perfect when you need images with a specific size for your templates but want your
users or editors to upload images of any dimension. It presents a selection with a fixed aspect ratio so your users
can’t break the layout with oddly-sized images.The original images are kept intact and only get cropped when they are displayed.
Large images are presented in a small format, so even very big images can easily be cropped.The necessary fields, widgets and a template tag for displaying the
cropped image in your templates are provided.Also works withFeinCMScontent types!InstallationInstall django-image-cropping usingpip:pip install django-image-croppingBy defaultdjango-image-croppingships with aneasy-thumbnails-backend which requireseasy-thumbnailsto also be installed
and added to theINSTALLED_APPS.Theeasy-thumbnailsbackend requires that you adjust the thumbnail processors in yoursettings:INSTALLED_APPS = [
    ...
    'easy_thumbnails',
    'image_cropping',
]

from easy_thumbnails.conf import Settings as thumbnail_settings
THUMBNAIL_PROCESSORS = (
    'image_cropping.thumbnail_processors.crop_corners',
) + thumbnail_settings.THUMBNAIL_PROCESSORSConfigurationAdd anImageRatioFieldto the model that contains theImageFieldfor the images you want to crop.TheImageRatioFieldsimply stores the boundaries of the cropped image.
It expects the name of the associatedImageFieldand the desired size of the cropped image as arguments.The size is passed in as a string and defines the aspect ratio of the selectionas wellas the minimum
size for the final image:from django.db import models
from image_cropping import ImageRatioField

class MyModel(models.Model):
    image = models.ImageField(blank=True, upload_to='uploaded_images')
    # size is "width x height"
    cropping = ImageRatioField('image', '430x360')You can configure asize warningif users try to crop a selection smaller than the defined minimum.Admin IntegrationAdd theImageCroppingMixinto yourModelAdmin:from django.contrib import admin
from image_cropping import ImageCroppingMixin

class MyModelAdmin(ImageCroppingMixin, admin.ModelAdmin):
    pass

admin.site.register(MyModel, MyModelAdmin)If your setup is correct you should now see the enhanced image widget that provides a selection
area.Backendsdjango-image-cropping delegates the cropped image generation to a backend.A backend based oneasy-thumbnailsis provided, but it’s possible to use a custom backend.
TheIMAGE_CROPPING_BACKENDsetting expects a dotted path to a class that implements the required methods.
You can omit this setting if you want to use the default backend.In case you use a custom backend you can provide an optional dict that will be used to populate the backend’s
constructor params.Default settings:IMAGE_CROPPING_BACKEND = 'image_cropping.backends.easy_thumbs.EasyThumbnailsBackend'
IMAGE_CROPPING_BACKEND_PARAMS = {}Frontenddjango-image-cropping provides a templatetag for displaying a cropped thumbnail.
Any other processor parameter (likebw=Trueorupscale=True) will be forwarded to the backend:{% cropped_thumbnail yourmodelinstance "ratiofieldname" [scale=INT|width=INT|height=INT|max_size="INTxINT"] %}Example usage:{% load cropping %}
<img src="{% cropped_thumbnail yourmodel "cropping" scale=0.5 %}">Or generate the URL from Python code in your view:from image_cropping.utils import get_backend
thumbnail_url = get_backend().get_thumbnail_url(
    yourmodel.image,
    {
        'size': (430, 360),
        'box': yourmodel.cropping,
        'crop': True,
        'detail': True,
    }
)easy_thumbnailsYou can also use the standardeasy-thumbnailstemplatetag with theboxparameter:{% load thumbnail %}
{% thumbnail yourmodel.image 430x360 box=yourmodel.cropping crop detail %}Or generate the URL from Python code in your view:from easy_thumbnails.files import get_thumbnailer
thumbnail_url = get_thumbnailer(yourmodel.image).get_thumbnail({
    'size': (430, 360),
    'box': yourmodel.cropping,
    'crop': True,
    'detail': True,
}).urlModelFormIf you want to use the cropping widget outside the admin, you’ll need to define theImageFieldas
anImageCropField:from django.db import models
from image_cropping import ImageCropField, ImageRatioField

class MyModel(models.Model):
    image = ImageCropField(blank=True, upload_to='uploaded_images')
    # size is "width x height"
    cropping = ImageRatioField('image', '430x360')Alternatively, override the widget in your ModelForm (you just need to do one of these two, not both!):from django import forms
from image_cropping import ImageCropWidget

class MyModelForm(forms.ModelForm):
    class Meta:
        widgets = {
            'image': ImageCropWidget,
        }Remember to include the form media in the<head>of your HTML:<html>
  <head>
    {{ form.media }}
  </head>
  <body>
    {{ form }}
  </body>
</html>The cropping itself happens in theImageRatioField, theImageCropFieldwill still behave like a regularImageField.If you’re selectively including or excluding fields from the ModelForm, remember to include theImageRatioField.Multiple formatsIf you need the same image in multiple formats, simply specify anotherImageRatioField.
This will allow the image to be cropped twice:from image_cropping import ImageRatioField, ImageCropField

image = ImageCropField(blank=True, upload_to='uploaded_images')
# size is "width x height"
list_page_cropping = ImageRatioField('image', '200x100')
detail_page_cropping = ImageRatioField('image', '430x360')In your templates, use the corresponding ratio field:{% load cropping %}
{% cropped_thumbnail yourmodel "list_page_cropping" %}Foreign KeysIf you need to crop an image contained within another model, referenced by a ForeignKey, theImageRatioFieldis
composed of theForeignKeyname, a double underscore, and theImageFieldname:from django.db import models
from image_cropping.fields import ImageRatioField

class Image(models.Model):
    image_field = models.ImageField(upload_to='image/')

class NewsItem(models.Model):
    title = models.CharField(max_length=255)
    image = models.ForeignKey(Image)
    cropping = ImageRatioField('image__image_field', '120x100')Cropping foreign keys only works in the admin for now, as it reuses theraw_idwidget.Free croppingIf you do not need afixedratio, you can disable this constraint by settingfree_croptoTrue.
In this case the size parameter is the desired minimum and is also used for the size-warning:from image_cropping import ImageRatioField, ImageCropField

image = ImageCropField(blank=True, upload_to='uploaded_images')

# size is "width x height" so a minimum size of 200px x 100px would look like this:
min_free_cropping = ImageRatioField('image', '200x100', free_crop=True)Use themax_sizeparameter of the templatetag if you want to limit the display size of a thumbnail:<img src="{% cropped_thumbnail image "cropping_free" max_size="200x200" %}" />Disabling croppingIf you want cropping to be optional, useallow_fullsize=Trueas an additional keyword argument for yourImageRatioField.Editors can now switch off cropping by unchecking a checkbox next to the image cropping widget:image_with_optional_cropping = ImageRatioField('image', '200x100', allow_fullsize=True)SettingsThumbnail sizeYou can define the maximum size of the admin preview thumbnail in yoursettings:# size is "width x height"
IMAGE_CROPPING_THUMB_SIZE = (300, 300)Size warningYou can warn users about crop selections that are smaller than the size defined in theImageRatioField.
When users try to do a smaller selection, a red border appears around the image.To use this functionality for a single image add thesize_warningparameter to theImageRatioField:cropping = ImageRatioField('image', '430x360', size_warning=True)You can enable this functionality project-wide by adding the following line to yoursettings:IMAGE_CROPPING_SIZE_WARNING = TrueCustom jQueryBy default the image cropping widget uses the jQuery version vendored with the Django admin.You can point to another version using theIMAGE_CROPPING_JQUERY_URLsetting, though compatibility
issues may arise if your jQuery version differs from the one that is tested against.You can also setIMAGE_CROPPING_JQUERY_URLtoNoneto disable inclusion of jQuery by the widget.
You are now responsible for includingjQueryyourself, both in the frontend and in the admin interface.Custom backendYou can define a custom backend:IMAGE_CROPPING_BACKEND = 'image_cropping.backends.easy_thumbs.EasyThumbnailsBackend'You can provide an optional dict that will be used to populate the backend’s
constructor:IMAGE_CROPPING_BACKEND_PARAMS = {'version_suffix': 'thumb'}See the built-in backends onBackends.TestingSetup a virtualenv with one of the supported versions of PythonInstall the example project:pip install-rexample/requirements.txtRunpytestIn case you want to test against multiple Python versions install and runtoxTroubleshootingThe cropping widget is not displayed when using aForeignKey.Make sure you donotadd the corresponding image field toraw_id_fields.Changelog1.7Add support for Django 4.0 (@jwedelin#176)1.6.2Use the jQuery bundled with Django as the default jQuery for image cropping1.6.1Add default setting for jquery url to app conf1.6Add support for Django 3.2Add support for Python 3.91.5Drop support for Python 3.5 (although it should still work)Add support for Django 3.1Minified JS and reduce potential for incompatibility with other django libraries (See #148)Fix formfield_for_dbfield signature (#134)Fix CSS property word separator (#131)Enforce isort in tests1.4Removed more old codeMove testing and packaging to GitHub Actions1.3Add support for Django 3.0Drop support for Python < 3.5Drop support for Django < 2.21.2Add support for Django 2.11.1Make django-image-cropping compatible with Django 1.111.0.4Move and encapsulate the logic for creating cropped thumbnails to a swappable backend. (@fgmacedoin #92)1.0“If your software is being used in production, it should probably already be 1.0.0.” (http://semver.org)0.9This release addresses mainly the test coverage and internal stuff.Noteable (breaking) changes and things to be considered when upgrading from an older version:django-appconfis now used for handling defaults and settings.Breaking Change: JQUERY_URL changed to IMAGE_CROPPING_JQUERY_URL as part of this transition.Thecropped_thumbnailtag is now based on Django’ssimple tag.Breaking Change: Arguments for the the tag now need to be put in quotes.If you are still using Django 1.4 remember thatyou can’t easily useTrueorFalseas template tag arguments.Any processor parameter (like bw=True or upscale=True) can be used in thecropped_thumbnailtag.Moved inline css to a dedicatedimage_cropping.cssstyle sheet0.8Minimumrequirements changed toDjango 1.4andeasy-thumbnails 1.4Added Python 3 compatibility. Python 2.6 is now the minimum required Python version.Added afree croppingoption, so cropping is no longer restricted to fixed ratios.Removed the deprecatedCropForeignKeyfield.0.7Made the widget for theImageCropFieldoverwritable to allow custom widgets. (Remember to use theImageCroppingMixinin the admin as the image cropping widgets are no longer implicitly set.)UpdatedJcropandjQuerydependencies.Moved docs toRead the Docs:https://django-image-cropping.readthedocs.org