Resizing and cropping images

WORKING WITH IMAGES


Resizing and Cropping Images

Resizing and cropping images in Django is useful when you want to ensure that uploaded images fit specific dimensions or aspect ratios. Django, combined with the Pillow library, provides several ways to achieve this within your models or views.

1. Installing Pillow

Just as in the previous section, you’ll need the Pillow library to manipulate images. If you haven't installed it yet, use the following command:


pip install Pillow

2. Resizing Images

To resize images, you can override the save() method in your model. This method will automatically resize the image upon upload before saving it to the database.


from django.db import models
from PIL import Image

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    profile_pic = models.ImageField(upload_to='profiles/', default='default.jpg')

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        img = Image.open(self.profile_pic.path)

        if img.height > 300 or img.width > 300:
            output_size = (300, 300)
            img.thumbnail(output_size)
            img.save(self.profile_pic.path)

In this example, the uploaded image is resized to 300x300 pixels if its dimensions exceed this size. The thumbnail() method ensures that the aspect ratio is maintained.

3. Cropping Images

In cases where you need to crop an image to a specific size, you can use Pillow’s crop() method. Below is an example where the image is cropped to a centered 200x200 square:


from django.db import models
from PIL import Image

class Banner(models.Model):
    title = models.CharField(max_length=100)
    banner_image = models.ImageField(upload_to='banners/')

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        img = Image.open(self.banner_image.path)
        width, height = img.size
        left = (width - 200) / 2
        top = (height - 200) / 2
        right = (width + 200) / 2
        bottom = (height + 200) / 2
        img = img.crop((left, top, right, bottom))
        img.save(self.banner_image.path)

This code snippet crops the center of the image to a 200x200 size. You can adjust the dimensions by modifying the crop coordinates.

4. Handling Different Aspect Ratios

Sometimes, you'll want to enforce a specific aspect ratio (e.g., 16:9) while resizing images. This is a common requirement for banners or thumbnails. Here's how to resize an image while maintaining the 16:9 aspect ratio:


from django.db import models
from PIL import Image

class Thumbnail(models.Model):
    title = models.CharField(max_length=100)
    thumbnail_image = models.ImageField(upload_to='thumbnails/')

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        img = Image.open(self.thumbnail_image.path)

        # Resize to maintain a 16:9 aspect ratio
        width, height = img.size
        aspect_ratio = 16 / 9

        if width / height > aspect_ratio:
            new_width = height * aspect_ratio
            img = img.crop(((width - new_width) / 2, 0, (width + new_width) / 2, height))
        else:
            new_height = width / aspect_ratio
            img = img.crop((0, (height - new_height) / 2, width, (height + new_height) / 2))

        img = img.resize((640, 360))  # Final resize to 640x360
        img.save(self.thumbnail_image.path)

This code ensures that the image is cropped to the center and resized to fit a 16:9 aspect ratio (640x360 in this case).

5. Conclusion

Resizing and cropping images in Django is an essential feature for applications that require uniform image dimensions or specific aspect ratios. With the power of Pillow, you can handle these tasks directly within your models.