# How to reduce the image file size using PIL

Posted on

### Question :

How to reduce the image file size using PIL

I am using PIL to resize the images there by converting larger images to smaller ones. Are there any standard ways to reduce the file size of the image without losing the quality too much, lets say the original size of the image is 100KB, i want to get it down to like 5 or 10 KB especially for png and jpeg formats.

A built-in parameter for saving JPEGs and PNGs is optimize.

 >>> from PIL import Image
# My image is a 200x374 jpeg that is 102kb large
>>> foo = Image.open("path\to\image.jpg")
>>> foo.size
(200,374)
# I downsize the image with an ANTIALIAS filter (gives the highest quality)
>>> foo = foo.resize((160,300),Image.ANTIALIAS)
>>> foo.save("path\to\save\image_scaled.jpg",quality=95)
# The saved downsized image size is 24.8kb
>>> foo.save("path\to\save\image_scaled_opt.jpg",optimize=True,quality=95)
# The saved downsized image size is 22.9kb


The optimize flag will do an extra pass on the image to find a way to reduce its size as much as possible. 1.9kb might not seem like much, but over hundreds/thousands of pictures, it can add up.

Now to try and get it down to 5kb to 10 kb, you can change the quality value in the save options.
Using a quality of 85 instead of 95 in this case would yield:
Unoptimized: 15.1kb
Optimized : 14.3kb
Using a quality of 75 (default if argument is left out) would yield:
Unoptimized: 11.8kb
Optimized : 11.2kb

I prefer quality 85 with optimize because the quality isn’t affected much, and the file size is much smaller.

lets say you have a model called Book and on it a field called ‘cover_pic’,
in that case, you can do the following to compress the image:

from PIL import Image
b = Book.objects.get(title='Into the wild')
image = Image.open(b.cover_pic.path)
image.save(b.image.path,quality=20,optimize=True)


hope it helps to anyone stumbling upon it.

The main image manager in PIL is PIL‘s Image module.

from PIL import Image
import math

foo = Image.open("path\to\image.jpg")
x, y = foo.size
x2, y2 = math.floor(x-50), math.floor(y-20)
foo = foo.resize((x2,y2),Image.ANTIALIAS)
foo.save("path\to\save\image_scaled.jpg",quality=95)


You can add optimize=True to the arguments of you want to decrease the size even more, but optimize only works for JPEG’s and PNG’s.
For other image extensions, you could decrease the quality of the new saved image.
You could change the size of the new image by just deleting a bit of code and defining the image size and you can only figure out how to do this if you look at the code carefully.
I defined this size:

x, y = foo.size
x2, y2 = math.floor(x-50), math.floor(y-20)


just to show you what is (almost) normally done with horizontal images.
For vertical images you might do:

x, y = foo.size
x2, y2 = math.floor(x-20), math.floor(y-50)


. Remember, you can still delete that bit of code and define a new size.

See the thumbnail function of PIL’s Image Module. You can use it to save smaller versions of files as various filetypes and if you’re wanting to preserve as much quality as you can, consider using the ANTIALIAS filter when you do.
__import__("importlib").import_module("PIL.Image").open("out.png").save("out.png")