Learning Outcomes
- To learn how to convert a single image into different image formats such as .png, .jpg and .Webp
- To learn how to convert multiple .png & .jpg images within the current working directory into .Webp images.
- To Learn how to combine image resizing & converting images into the .Webp format.
With the rise of recommended speed changes from Google including Web Vitals, its crucial that your website or web application is able to serve better image formats.
In this tutorial, you’ll learn how to convert image formats into next-generation formats using Python.
What Are Next Generation Image Formats And Why Are They Important?
Next generation image formats include:
- JPEG 2000
- JPEG XR
- WebP
All of the above formats have better compression and are higher in quality when compared to their previous PNG and JPEG counterparts.
Encoding your images into one of the above formats ensures that your images will use less data, cost you less money and ensures your applications load faster for your users.
Check Browser Compatibility
Currently there isn’t true browser support for all of the next-generation image formats, therefore it’s recommended that you provide either a fallback JPEG or PNG image for older browsers.
Module Imports
from PIL import Image
import PIL
import os
import glob
You can easily load an image from a file, using the open() found within the Image module:
image = image.open('image-filepath.png')
image.show()
Image Conversions In Python
You can convert an image into a different format by:
- Opening the image.
- Converting the image to RGB colour.
- Saving the image as a different file.
# 1. Open The Image:
image = Image.open('example.jpg')
# 2. Convert the image to RGB Colour:
image = image.convert('RGB')
# 3. Save The Image:
image.save('example-test.png', 'png')
Extra Information About The Functions:
Image.convert() returns a converted image copy. For the “P” mode, the method translates pixels through the palette. However, if mode is omitted, a mode is chosen so that all information in the image and the palette is represented without a palette.
The Image.save() requires two arguments, the first one is the file path (or file name) and the second one is the file format that you would like to save the image as.
Common Image Conversions In Python
Let’s practice some common image conversions using the Pillow Library!
!ls
changing-image-types-and-next-generation-formats.ipynb
example-1.png
example-2.jpg
PNG to JPG
image = Image.open('example-1.png')
image = image.convert('RGB')
image.save('new-image.jpg', 'jpeg')
JPG to PNG
image = Image.open('example-2.jpg')
image = image.convert('RGB')
image.save('new-image.png', 'png')
If you check your current working directory, you’ll now see two extra images:
PNG to WebP
image = Image.open('example-1.png')
image = image.convert('RGB')
image.save('new-format-image-from-png.webp', 'webp')
JPG to WebP
image = Image.open('example-2.jpg')
image = image.convert('RGB')
image.save('new-format-image-from-jpeg.webp', 'webp')
WebP to PNG
image = Image.open('new-format-image-from-png.webp')
image = image.convert('RGB')
image.save('converting-from-webp-to-png-format.png', 'png')
WebP to JPG
image = Image.open('new-format-image-from-png.webp')
image = image.convert('RGB')
image.save('converting-from-webp-to-jpg-format.jpg', 'jpeg')
Converting All The Images In Your Current Working Directory Into .WebP Format
Let’s create a python function which will convert any .png or .jpeg files from the current working directory into .webp images!
files = os.listdir() # We list all of the files and folders using os.listdir()
print(f"These are all of the files in our current working directory: {files}")
These are all of the files in our current working directory: ['.DS_Store', 'converting-from-webp-to-png-format.png', 'new-format-image-from-png.webp', 'converting-from-webp-to-jpg-format.jpg', 'new-format-image-from-jpeg.webp', '.ipynb_checkpoints', 'example-1.png', 'new-image.jpg', 'example-2.jpg', 'new-image.png', 'changing-image-types-and-next-generation-formats.ipynb']
We will also filter to only retrieve files ending in jpg or png:
images = [file for file in files if file.endswith(('jpg', 'png'))]
print(f"These are all of the images in our current working directory {images}")
These are all of the images in our current working directory ['converting-from-webp-to-png-format.png', 'converting-from-webp-to-jpg-format.jpg', 'example-1.png', 'new-image.jpg', 'example-2.jpg', 'new-image.png']
# Defining a Python user-defined exception
class Error(Exception):
"""Base class for other exceptions"""
pass
def convert_image(image_path, image_type):
# 1. Opening the image:
im = Image.open(image_path)
# 2. Converting the image to RGB colour:
im = im.convert('RGB')
# 3. Spliting the image path (to avoid the .jpg or .png being part of the image name):
image_name = image_path.split('.')[0]
print(f"This is the image name: {image_name}")
# Saving the images based upon their specific type:
if image_type == 'jpg' or image_type == 'png':
im.save(f"Converted-to-next-gen-format-{image_name}.webp", 'webp')
else:
# Raising an error if we didn't get a jpeg or png file type!
raise Error
for image in images:
if image.endswith('jpg'):
convert_image(image, image_type='jpg')
elif image.endswith('png'):
convert_image(image, image_type='png')
else:
raise Error
This is the image name: converting-from-webp-to-png-format
This is the image name: converting-from-webp-to-jpg-format
This is the image name: example-1
This is the image name: new-image
This is the image name: example-2
This is the image name: new-image
# Deleting any files that contain the string Converted
[os.remove(file) for file in os.listdir() if 'Converted' in file]
After learning how to convert multiple .jpg or .png files into .webp files, with a list comprehension expression we can also execute the convert_image functions one by one:
[convert_image(image, image_type='jpg') if image.endswith('jpg') else
convert_image(image, image_type='png') for image in images]
Deleting All Of The Files Created:
string_matches = ['Converted', 'converting', 'new']
for file in os.listdir():
if any(x in file for x in string_matches):
os.remove(file)
!ls
# changing-image-types-and-next-generation-formats.ipynb
# example-1.png
# example-2.jpg
Combining Image Resizing With Converting Images To .Webp
As a final task, let’s slightly change the convert_image function so that it automatically detects the image size.
- If the image is above 600px in width, we’ll set the a custom width and will dynamically re-size it before converting it into a .Webp image.
def convert_image(image_path, image_type, custom_size=300):
# 1. Opening the image:
im = Image.open(image_path)
# 2. Converting the image to RGB colour:
im = im.convert('RGB')
# 3. Spliting the image path (to avoid the .jpg or .png being part of the image name):
image_name = image_path.split('.')[0]
print(f"This is the image name: {image_name}")
# Saving the images based upon their specific type:
if image_type == 'jpg' or image_type == 'png':
if im.size[0] > 600:
im.thumbnail(size=((custom_size, custom_size)))
im.save(f"Converted-to-next-gen-format-{image_name}.webp", 'webp')
else:
im.save(f"Converted-to-next-gen-format-{image_name}.webp", 'webp')
else:
# Raising an error if we didn't get a jpeg or png file type!
raise Error
images = [file for file in os.listdir() if file.endswith(('jpg', 'png'))]
[convert_image(image, image_type='jpg', custom_size=200) if image.endswith('jpg') else
convert_image(image, image_type='png', custom_size=200) for image in images]
Deleting All Of The Files Created:
string_matches = ['Converted', 'converting', 'new']
for file in os.listdir():
if any(x in file for x in string_matches):
os.remove(file)
Pillow is a great image processing library and by combining image compression with resizing and next-generation image formats, you’ll be able to create high quality imagery without sacrificing on user experience.