Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Losslessly compressing images on django

People also ask

How do I compress an image without losing quality python?

Those who know a bit of python can install python and use pip install pillow in command prompt(terminal for Linux users) to install pillow fork. Assemble all the files in a folder and keep the file Compress.py in the same folder. Run the python file with python.

Do images lose quality when compressed?

Compressing JPEG images downgrades the quality of the image.

How do I compress a .img file?

Open the photo you want to compress in your photo-editing software. Go to the file menu in your software and choose Save As or Save. Click on Options in the pop-up menu. Select High Compression in the Photo Compression section of the menu.


Losslessly compressing http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg could save 594.3KiB (92% reduction).

First of all, the information in the logs is not very accurate.

92% lossless reduction is only possible when the original image is uncompressed and has very small number of colours (ideally less than 256).

Lossless compression involves reducing the "bit-depth" of an image, i.e. converting 24-bit images down to 8-bit if there are less than 256 colours, that means you're saving 16 bits per pixel. But that doesn't seem possible for the images you've linked because they have well over 256 colours.

Second, you can use lossy compression formats "without losing quality" – the differences are so subtle, human eye doesn't even notice.

Read this answer and this answer for more info. Really, do read them, both are excellent answers related to this issue.


So, I downloaded an image from the website you're optimizing from this link: http://www.kenyabuzz.com/media/uploads/clients/kenya_buzz_2.jpg

I opened my Python console and wrote this:

>>> from PIL import Image

>>> # Open the image
>>> im = Image.open("kenya_buzz_2.jpg")
>>> # Now save it
>>> im.save("kenya_buzz_compressed.jpg", format="JPEG", quality=70)

This created a new image on my disk. Below are both the images.

Original (655.3kB)

original image


Compressed (22.4kB ~96% reduction @ quality=70)

compressed image using Python


You can play around with the quality option. Like, value of 80 will give you a better quality image but with a little larger size.


Compressing images in Django

Since this is a pretty popular question, I've decided to add a sample code to compress images in Django.

This code works for Django >= 1.7.

from io import BytesIO
from PIL import Image
from django.core.files import File


def compress(image):
    im = Image.open(image)
    # create a BytesIO object
    im_io = BytesIO() 
    # save image to BytesIO object
    im.save(im_io, 'JPEG', quality=70) 
    # create a django-friendly Files object
    new_image = File(im_io, name=image.name)
    return new_image

And this is how you can use the above compress function in your Django model (or anywhere):

# models.py

class MyModel(...):
    image = models.ImageField(...)

    def save(self, *args, **kwargs):
        # call the compress function
        new_image = compress(self.image)
        # set self.image to new_image
        self.image = new_image
        # save
        super().save(*args, **kwargs)

That is basically it. This is fairly basic code. You can improve the code by compressing the image only when the image changes, not every time the model is saved.


You should try Django Easy Thumbnails app, it has some options to add a postprocessing to optimize uploaded images : PostProcessor documentation

I use it in production on several projects. It works well, image size is definitely smaller and page loading much more faster.


I have no experience with it, however, picopt looks comprehensive. It relies extensively on external tools to perform the optimisation, so it might be difficult to set up in constrained or hosted server environments.

Other than that, try googling "python image optimization". There are a few other links that suggest that a PIL based solution might be possible, for example:

  1. How to reduce the image file size using PIL
  2. Image Optimization (Google App Engine with Python)