{"id":177473,"date":"2026-02-19T14:13:40","date_gmt":"2026-02-19T13:13:40","guid":{"rendered":"https:\/\/liora.io\/en\/?p=177473"},"modified":"2026-02-19T14:13:40","modified_gmt":"2026-02-19T13:13:40","slug":"pillow-how-to-process-images-with-python","status":"publish","type":"post","link":"https:\/\/liora.io\/en\/pillow-how-to-process-images-with-python","title":{"rendered":"Pillow: How to process images with Python"},"content":{"rendered":"<p><strong>Formerly known as PIL, Pillow is an open source library specifically designed for image processing via Python. A veritable goldmine for image file manipulation, let&#8217;s take a look at some of the basic features of this benchmark library.<\/strong><\/p>\n<!-- \/wp:post-content -->\n\n<!-- wp:heading -->\n<h2 id=\"h-what-is-pillow-the-python-library\" class=\"wp-block-heading\">What is Pillow, the Python library?<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Originally designed by Fredrik Lundh in 1995, Python Imaging Library abbreviated PIL was the reference library for <a href=\"https:\/\/liora.io\/en\/image-processing-fundamental-principles-and-practical-uses\">image processing<\/a> on Python. Abandoned in 2009, the project&#8217;s source code was taken over by Alex Clark, who published a new version called Pillow in 2010, definitively replacing PIL.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Unlike other libraries offering only a few image processing methods, <strong>Pillow<\/strong> is almost exclusively focused on image processing. It is therefore far more comprehensive and optimized for image manipulation. For this reason, Pillow is regularly used in the key stages of a computer vision or video processing project, despite the existence of more general libraries such as OpenCV or MoviePy.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>In all, no fewer than 30 image formats are supported by this module. These include the usual JPG, PNG, JPEG and GIF files, as well as more specific extensions such as BLP (used by the famous game World of Warcraft), DDS (also prolific in the video game industry) and FITS (used in astronomy).<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>One of Pillow&#8217;s main attractions is its ease of use. Notations are natural, and the underlying classes and methods have been well thought out to facilitate the user experience. It&#8217;s this user-friendly aspect that we&#8217;re going to highlight in this introductory article. The aim is to present a series of methods that you will come to use, from the simplest to the slightly more sophisticated.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 id=\"h-the-image-class-at-the-heart-of-pillow\" class=\"wp-block-heading\">The Image class at the heart of Pillow<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 id=\"h-importing-an-image-into-python\" class=\"wp-block-heading\">Importing an image into Python<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Within this vast library lies a class soberly entitled Image. It contains a whole collection of essential methods for getting started with image processing. Let&#8217;s take a look at a very basic example below:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code {\"style\":{\"spacing\":{\"margin\":{\"top\":\"var:preset|spacing|columns\",\"bottom\":\"var:preset|spacing|columns\"}}},\"fontSize\":\"xsmall\"} -->\n<pre class=\"wp-block-code has-xsmall-font-size\" style=\"margin-top:var(--wp--preset--spacing--columns);margin-bottom:var(--wp--preset--spacing--columns)\"><code>from PIL import Image\n\nim = Image.open(\"logoDST.jpg\")\n\nprint(im.format, im.size, im.mode)\n\nim.show()<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>The first step is to import the Image class from the PIL module. Rather than importing the entire Pillow library, it&#8217;s a good idea to add only those elements that are relevant to our project.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Next, we declare an im variable of type Image via the open() method. To keep things simple, we&#8217;ve stored the image file logoDST.jpg in the new variable.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"align\":\"center\",\"style\":{\"spacing\":{\"margin\":{\"top\":\"var:preset|spacing|columns\",\"bottom\":\"var:preset|spacing|columns\"}}}} -->\n<figure class=\"wp-block-image aligncenter\" style=\"margin-top:var(--wp--preset--spacing--columns);margin-bottom:var(--wp--preset--spacing--columns)\"><img decoding=\"async\" src=\"https:\/\/liora.io\/app\/uploads\/2023\/04\/image4-6-e1681838949757.png\" alt=\"\" title=\"\"><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>The third line displays some of the file properties available in the class attributes: format, size and mode (grayscale, RGB, CMYK&#8230;) and finally, the last line displays the image in question. Note that on an .ipynb file (Jupyter Notebook), this line must be replaced by display(im) in order to display the image in question!<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 id=\"h-change-format-and-create-a-thumbnail\" class=\"wp-block-heading\">Change format and create a thumbnail<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>As with any<a href=\"https:\/\/liora.io\/en\/exploring-imageio-a-comprehensive-guide-to-the-python-library\"> image processing library<\/a> worthy of the name, you can modify the nature of your :<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code {\"style\":{\"spacing\":{\"margin\":{\"top\":\"var:preset|spacing|columns\",\"bottom\":\"var:preset|spacing|columns\"}}},\"fontSize\":\"xsmall\"} -->\n<pre class=\"wp-block-code has-xsmall-font-size\" style=\"margin-top:var(--wp--preset--spacing--columns);margin-bottom:var(--wp--preset--spacing--columns)\"><code>import os, sys\nfrom PIL import Image\n\nfor infile in sys.argv[1:]:\n    f, e = os.path.splitext(infile)\n    outfile = f + \".jpg\"\n    if infile != outfile:\n        try:\n            with Image.open(infile) as im:\n                im.save(outfile)\n        except OSError:\n            print(\"cannot convert\", infile)<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>This snippet converts a file into JPG format. To specify a particular format, you need to mention it in the second parameter of the save() function. An application of this principle can be seen in the next snippet, which creates a thumbnail for the .JPEG file.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code {\"style\":{\"spacing\":{\"margin\":{\"top\":\"var:preset|spacing|columns\",\"bottom\":\"var:preset|spacing|columns\"}}},\"fontSize\":\"xsmall\"} -->\n<pre class=\"wp-block-code has-xsmall-font-size\" style=\"margin-top:var(--wp--preset--spacing--columns);margin-bottom:var(--wp--preset--spacing--columns)\"><code>import os, sys\nfrom PIL import Image\n\nsize = (128, 128)\n\nfor infile in sys.argv[1:]:\n    outfile = os.path.splitext(infile)[0] + \".thumbnail\"\n    if infile != outfile:\n        try:\n            with Image.open(infile) as im:\n                im.thumbnail(size)\n                im.save(outfile, \"JPEG\")\n        except OSError:\n            print(\"cannot create thumbnail for\", infile)<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>Finally, it is also possible to recognize the format of a file with the following command:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code {\"style\":{\"spacing\":{\"margin\":{\"top\":\"var:preset|spacing|columns\",\"bottom\":\"var:preset|spacing|columns\"}}},\"fontSize\":\"xsmall\"} -->\n<pre class=\"wp-block-code has-xsmall-font-size\" style=\"margin-top:var(--wp--preset--spacing--columns);margin-bottom:var(--wp--preset--spacing--columns)\"><code>import sys\nfrom PIL import Image\n\nfor infile in sys.argv[1:]:\n    try:\n        with Image.open(infile) as im:\n            print(infile, im.format, f\"{im.size}x{im.mode}\")\n    except OSError:\n        pass<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:buttons {\"className\":\"is-layout-flex wp-block-buttons-is-layout-flex is-content-justification-center\",\"layout\":{\"type\":\"flex\",\"justifyContent\":\"center\"}} -->\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex is-content-justification-center\"><!-- wp:button -->\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/liora.io\/en\/courses\/data-ai\/data-scientist\">Tout apprendre sur Pillow<\/a><\/div>\n<!-- \/wp:button --><\/div>\n<!-- \/wp:buttons -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 id=\"h-transform-an-image-in-no-time\" class=\"wp-block-heading\">Transform an image in no time<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>As mentioned in Part 1, <strong>Pillow&#8217;s<\/strong> main strength lies in its wide range of transformation functions and their ease of use.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>To illustrate this point, we&#8217;re going to perform a series of transformations on a source image.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Below, we have visualized the effect of 5 basic transformations on a source image (called &#8220;Original&#8221;).<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"align\":\"center\",\"style\":{\"spacing\":{\"margin\":{\"top\":\"var:preset|spacing|columns\",\"bottom\":\"var:preset|spacing|columns\"}}}} -->\n\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>Each figure is associated with the one and only line of code required to recreate the<strong> image displayed<\/strong>. So, for example, im.convert(&#8220;L&#8221;) converts the image mode to grayscale, and just as simply, we can cropper, transpose, resize or rotate an image.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h4 id=\"h-photo-retouching-with-imageenhance\" class=\"wp-block-heading\">Photo retouching with ImageEnhance<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>The <strong>ImageEnhance module<\/strong> contains four classes for controlling the parameters most commonly used in photographic retouching: sharpness, white balance, contrast and brightness. Each of these classes contains a single method called enhance(), taking as parameter a numerical value corresponding to the enhancement factor: expressed as a ratio, a parameter set to 1.0 will simply return a carbon copy of the input image.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Contrast defines the relative scale of difference between <a href=\"https:\/\/liora.io\/en\/google-partners-with-adobe-for-a-more-ethical-image-generation\">light and dark parts of an image.<\/a> Color balance adjusts color intensity according to lighting conditions. Luminosity impacts the overall clarity of the image, unlike contrast. Finally, sharpness defines the fineness of detail in an image.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>You&#8217;ll be able to retouch your photos in just a few lines!<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"align\":\"center\"} -->\n\n<!-- \/wp:image -->\n\n<!-- wp:heading {\"level\":3} -->\n<h4 id=\"h-imagefilter-a-first-step-in-computer-vision\" class=\"wp-block-heading\">ImageFilter &#8211; a first step in Computer Vision<\/h4>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>If you&#8217;d like to <a href=\"https:\/\/liora.io\/en\/u-net-computer-visions-neural-network\">continue your computer vision adventure,<\/a> Pillow and the ImageFilter module are an excellent gateway to this attractive world. This is where you&#8217;ll find Gaussian blurring, detail enhancement and embossing operations. Many Computer Vision algorithms require this type of filtering, especially for edge detection.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"align\":\"center\",\"style\":{\"spacing\":{\"margin\":{\"top\":\"var:preset|spacing|columns\",\"bottom\":\"var:preset|spacing|columns\"}}}} -->\n<figure class=\"wp-block-image aligncenter\" style=\"margin-top:var(--wp--preset--spacing--columns);margin-bottom:var(--wp--preset--spacing--columns)\"><img decoding=\"async\" src=\"https:\/\/liora.io\/app\/uploads\/2023\/04\/image5.jpg\" alt=\"\" title=\"\"><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>To find out more about the<a href=\"https:\/\/liora.io\/en\/mushroom-recognition\"> basics of Computer Vision<\/a>, please consult our dedicated article.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 id=\"h-and-much-much-more\" class=\"wp-block-heading\">And much, much more!<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>If you&#8217;ve enjoyed this <strong>introduction to the PIL library,<\/strong> you&#8217;ll be pleased to know that this article has only scratched the surface of some of its features! It is indeed possible to add complexity to your image processing by, for example, creating custom shapes and merging different images&#8230;<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"align\":\"center\"} -->\n\n<!-- \/wp:image -->\n\n<!-- wp:buttons {\"className\":\"is-layout-flex wp-block-buttons-is-layout-flex is-content-justification-center\",\"layout\":{\"type\":\"flex\",\"justifyContent\":\"center\"}} -->\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex is-content-justification-center\"><!-- wp:button -->\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/liora.io\/en\/courses\/\">Getting started in Data Science<\/a><\/div>\n<!-- \/wp:button --><\/div>\n<!-- \/wp:buttons -->\n\n<!-- wp:html -->\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"FAQPage\",\n  \"mainEntity\": [\n    {\n      \"@type\": \"Question\",\n      \"name\": \"What is Pillow in Python?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Pillow is a popular Python imaging library used to open, manipulate, and save a wide range of image formats, providing high\u2011level functions for basic image processing tasks.\u00a0([turn0search0][turn0search3])\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"How do I open an image with Pillow?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"You can open an image in Python using Pillow by importing the Image class from PIL and calling Image.open(\\\"filename.jpg\\\"), which returns an Image object for further processing.\u00a0([turn0search0][turn0search4])\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"What basic image manipulations can I perform with Pillow?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"With Pillow you can crop, resize, rotate, transform, and change the format of images, such as creating thumbnails or rotating by specified angles.\u00a0([turn0search0][turn0search4])\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"Can Pillow apply filters to images?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Yes \u2014 Pillow\u2019s ImageFilter module lets you apply effects such as blurring, sharpening, edge detection, and other filters to enhance or alter images.\u00a0([turn0search0][turn0search2])\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"How can I save or convert images using Pillow?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Once processed, you can save images to disk using the .save() method of an Image object, and you can convert between formats by specifying the output format or changing the file extension.\u00a0([turn0search0][turn0search4])\"\n      }\n    }\n  ]\n}\n<\/script>\n\n<!-- \/wp:html -->","protected":false},"excerpt":{"rendered":"<p>Formerly known as PIL, Pillow is an open source library specifically designed for image processing via Python. A veritable goldmine for image file manipulation, let&#8217;s take a look at some of the basic features of this benchmark library. What is Pillow, the Python library? Originally designed by Fredrik Lundh in 1995, Python Imaging Library abbreviated [&hellip;]<\/p>\n","protected":false},"author":82,"featured_media":207524,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"editor_notices":[],"footnotes":""},"categories":[2434],"class_list":["post-177473","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud-dev"],"acf":[],"_links":{"self":[{"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/posts\/177473","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/users\/82"}],"replies":[{"embeddable":true,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/comments?post=177473"}],"version-history":[{"count":5,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/posts\/177473\/revisions"}],"predecessor-version":[{"id":207525,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/posts\/177473\/revisions\/207525"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/media\/207524"}],"wp:attachment":[{"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/media?parent=177473"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/liora.io\/en\/wp-json\/wp\/v2\/categories?post=177473"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}