Approximately 62 percent of today’s online content is made up of images, optimizing which is a must to speed up loading of media-rich websites. A fast-loading site makes your visitors happy, which as a rule leads to higher conversion rates.
This article shows you how to optimize images in the Python programming language.
Three major reasons account for why optimizing images for websites is important:
- SEO: Your website speed is a crucial ranking and engagement factor, that is, the site’s load time and overall size directly affect your search-engine ranking. Optimized images invariably cause sites to load faster.
- Storage: Optimized images result in smaller files, hence less storage space.
- Bandwidth: Optimized images save data bandwidth, correspondingly lowering hosting cost and visitors’ data usage.
You can optimize images in Python in one of the following ways:
- With Pillow, which extends the Python Imaging Library (PIL) by adding more features and support for Python 3. Pillow works with many image formats, including PNG, JPEG, PPM, GIF, TIFF, and BMP.
- With img4web, a Python script that optimizes JPEGs, PNGs, and animated GIFs on the web. The script produces lossless and only slightly compressed images, which nonetheless reduce load time and bandwidth.
- With smush.py, a Python command-line tool (derived from Yahoo’s smush.it service) that functions as a lossless image optimizer for displaying images.
- With Tinify, a Python package for compressing and optimizing JPEGs and PNGs by means of the Tinify API.
- With scikit-image, a Python image processing library with a versatile set of optimization and transformation routines, e.g.,
rescale
and resize
.
With Cloudinary, you can efficiently optimize media assets—regardless of programming language. One reason is that, by default, Cloudinary automatically performs certain optimization steps on all transformed images. Plus, its integrated, fast delivery capability through CDNs ensures that your images are seamlessly displayed on viewers’ devices.
Cloudinary offers the following optimization capabilities:
Automatic quality adjustment and encoding: Once you have set up the q_auto
parameter for an image, Cloudinary chooses the optimal quality-compression level and encoding settings according to the image content, its format, and the viewing browser. The result is a compressed image with superior visual quality. See this example:
Ruby:
cl_image_tag("woman.jpg", :quality=>"auto")
PHP v1:
cl_image_tag("woman.jpg", array("quality"=>"auto"))
PHP v2:
(new ImageTag('woman.jpg'))
->delivery(Delivery::quality(Quality::auto()));
Python:
CloudinaryImage("woman.jpg").image(quality="auto")
Node.js:
cloudinary.image("woman.jpg", {quality: "auto"})
Java:
cloudinary.url().transformation(new Transformation().quality("auto")).imageTag("woman.jpg");
JS:
cloudinary.imageTag('woman.jpg', {quality: "auto"}).toHtml();
jQuery:
$.cloudinary.image("woman.jpg", {quality: "auto"})
React:
<Image publicId="woman.jpg" >
<Transformation quality="auto" />
</Image>
Vue.js:
<cld-image publicId="woman.jpg" >
<cld-transformation quality="auto" />
</cld-image>
Angular:
<cl-image public-id="woman.jpg" >
<cl-transformation quality="auto">
</cl-transformation>
</cl-image>
.NET:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Quality("auto")).BuildImageTag("woman.jpg")
Android:
MediaManager.get().url().transformation(new Transformation().quality("auto")).generate("woman.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setQuality("auto")).generate("woman.jpg")!, cloudinary: cloudinary)
To fine-tune the visual quality of images, set up the q_auto:best
. q_auto:low
, q_auto:good
, or q_auto:eco
parameter, as you desire.
Automatic formatting: The f_auto
parameter enables Cloudinary to analyze the image content and selects the best format for delivery. For example, it might deliver images as WebP to Chrome or as JPEG-XR to Internet Explorer but retain the original format for all other browsers. With both f_auto
and q_auto
in place, Cloudinary would still deliver WebP and JPEG-XR to the relevant browsers. However, if the quality algorithm determines that PNG-8 or PNG-24 is the optimal format, Cloudinary might deliver selected images in either format.
Resizing and cropping: By adding the width (w
) and height (h
) parameters to image URLs, you direct Cloudinary to resize those images, as in this example:
Ruby:
cl_image_tag("sample.jpg", :width=>0.5, :crop=>"scale")
PHP v1:
cl_image_tag("sample.jpg", array("width"=>"0.5", "crop"=>"scale"))
PHP v2:
(new ImageTag('sample.jpg'))
->resize(Resize::scale()->width(0.5));
Python:
CloudinaryImage("sample.jpg").image(width="0.5", crop="scale")
Node.js:
cloudinary.image("sample.jpg", {width: "0.5", crop: "scale"})
Java:
cloudinary.url().transformation(new Transformation().width(0.5).crop("scale")).imageTag("sample.jpg");
JS:
cloudinary.imageTag('sample.jpg', {width: "0.5", crop: "scale"}).toHtml();
jQuery:
$.cloudinary.image("sample.jpg", {width: "0.5", crop: "scale"})
React:
<Image publicId="sample.jpg" >
<Transformation width="0.5" crop="scale" />
</Image>
Vue.js:
<cld-image publicId="sample.jpg" >
<cld-transformation width="0.5" crop="scale" />
</cld-image>
Angular:
<cl-image public-id="sample.jpg" >
<cl-transformation width="0.5" crop="scale">
</cl-transformation>
</cl-image>
.NET:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(0.5).Crop("scale")).BuildImageTag("sample.jpg")
Android:
MediaManager.get().url().transformation(new Transformation().width(0.5).crop("scale")).generate("sample.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setWidth(0.5).setCrop("scale")).generate("sample.jpg")!, cloudinary: cloudinary)
Ruby:
cl_image_tag("sample.jpg", :height=>200, :crop=>"scale")
PHP v1:
cl_image_tag("sample.jpg", array("height"=>200, "crop"=>"scale"))
PHP v2:
(new ImageTag('sample.jpg'))
->resize(Resize::scale()->height(200));
Python:
CloudinaryImage("sample.jpg").image(height=200, crop="scale")
Node.js:
cloudinary.image("sample.jpg", {height: 200, crop: "scale"})
Java:
cloudinary.url().transformation(new Transformation().height(200).crop("scale")).imageTag("sample.jpg");
JS:
cloudinary.imageTag('sample.jpg', {height: 200, crop: "scale"}).toHtml();
jQuery:
$.cloudinary.image("sample.jpg", {height: 200, crop: "scale"})
React:
<Image publicId="sample.jpg" >
<Transformation height="200" crop="scale" />
</Image>
Vue.js:
<cld-image publicId="sample.jpg" >
<cld-transformation height="200" crop="scale" />
</cld-image>
Angular:
<cl-image public-id="sample.jpg" >
<cl-transformation height="200" crop="scale">
</cl-transformation>
</cl-image>
.NET:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Height(200).Crop("scale")).BuildImageTag("sample.jpg")
Android:
MediaManager.get().url().transformation(new Transformation().height(200).crop("scale")).generate("sample.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setHeight(200).setCrop("scale")).generate("sample.jpg")!, cloudinary: cloudinary)
Here, Cloudinary maintains the aspect ratio but resizes the image to the height and width you specified.
Ruby:
cl_image_tag("sample.jpg", :width=>200, :height=>100, :crop=>"scale")
PHP v1:
cl_image_tag("sample.jpg", array("width"=>200, "height"=>100, "crop"=>"scale"))
PHP v2:
(new ImageTag('sample.jpg'))
->resize(Resize::scale()->width(200)->height(100));
Python:
CloudinaryImage("sample.jpg").image(width=200, height=100, crop="scale")
Node.js:
cloudinary.image("sample.jpg", {width: 200, height: 100, crop: "scale"})
Java:
cloudinary.url().transformation(new Transformation().width(200).height(100).crop("scale")).imageTag("sample.jpg");
JS:
cloudinary.imageTag('sample.jpg', {width: 200, height: 100, crop: "scale"}).toHtml();
jQuery:
$.cloudinary.image("sample.jpg", {width: 200, height: 100, crop: "scale"})
React:
<Image publicId="sample.jpg" >
<Transformation width="200" height="100" crop="scale" />
</Image>
Vue.js:
<cld-image publicId="sample.jpg" >
<cld-transformation width="200" height="100" crop="scale" />
</cld-image>
Angular:
<cl-image public-id="sample.jpg" >
<cl-transformation width="200" height="100" crop="scale">
</cl-transformation>
</cl-image>
.NET:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(100).Crop("scale")).BuildImageTag("sample.jpg")
Android:
MediaManager.get().url().transformation(new Transformation().width(200).height(100).crop("scale")).generate("sample.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setWidth(200).setHeight(100).setCrop("scale")).generate("sample.jpg")!, cloudinary: cloudinary)
Cloudinary supports many image-cropping modes: scale, fit, mfit, fill, lfill, limit, pad, lpad, mpad, crop, thumb, imagga_crop, and imagga_scale.
Properly optimizing and caching images is a crucial step toward enhancing website performance. The tips this post offers are just a start. See the Cloudinary documentation for more ideas on optimization of JPEG images without compromising quality and on image transformations.