Skip to content
Search

Python Imaging Library

lastmod 2025-11-14created 2019-08-056 edits

The Python Imaging Library (PIL) adds image processing capabilities to your Python interpreter. This library supports many file formats, and provides powerful image processing and graphics capabilities.

WARNING

No longer developed. See the successor project Pillow

The Python Imaging Library (PIL) is a free and open-source software library that adds support for many image file formats to the Python interpreter and provides powerful image processing and graphics capabilities. It is abbreviated as PIL. It supports Windows, Mac OS X, and Linux. The latest version of PIL is 1.1.7, released in September 2009, and it supports Python 1.5-2.7.

Development appears to have stopped with the last commit to the PIL repository in 2011, and a successor project called Pillow forked from the PIL repository and added Phthon 3.x support. As the successor to PIL, Pillow has been adopted to replace PIL in Linux distributions such as Debian and Ubuntu.

Install

pip install pillow

JPEG Image Quality in PIL

The quality parameter

The image quality, on a scale from 1 (worst) to 95 (best). The default is 75. Values above 95 should be avoided; 100 disables portions of the JPEG compression algorithm, and results in large files with hardly any gain in image quality.

Using a quality factor of 95 should be enough to preserve the image quality:

img.save('test.jpg', quality=95)

Subsampling

According to this post, even if you use quality=100, the saved image will still be slightly different from the original image. This is because PIL will also use subsampling technique to reduce the image size. You can use subsampling=0 to turn off this feature. Overall, to retain the content of original image, you may use:

img.save('test.jpg', quality=100, subsampling=0)

labelme2coco image utils

import base64
import io

import numpy as np
import PIL.ExifTags
import PIL.Image
import PIL.ImageOps


def img_data_to_pil(img_data):
    f = io.BytesIO()
    f.write(img_data)
    img_pil = PIL.Image.open(f)
    return img_pil


def img_data_to_arr(img_data):
    img_pil = img_data_to_pil(img_data)
    img_arr = np.array(img_pil)
    return img_arr


def img_b64_to_arr(img_b64):
    img_data = base64.b64decode(img_b64)
    img_arr = img_data_to_arr(img_data)
    return img_arr


def img_pil_to_data(img_pil):
    f = io.BytesIO()
    img_pil.save(f, format="PNG")
    img_data = f.getvalue()
    return img_data


def img_arr_to_b64(img_arr):
    img_pil = PIL.Image.fromarray(img_arr)
    f = io.BytesIO()
    img_pil.save(f, format="PNG")
    img_bin = f.getvalue()
    if hasattr(base64, "encodebytes"):
        img_b64 = base64.encodebytes(img_bin)
    else:
        img_b64 = base64.encodestring(img_bin)
    return img_b64


def img_data_to_png_data(img_data):
    with io.BytesIO() as f:
        f.write(img_data)
        img = PIL.Image.open(f)

        with io.BytesIO() as f:
            img.save(f, "PNG")
            f.seek(0)
            return f.read()


def apply_exif_orientation(image):
    try:
        exif = image._getexif()
    except AttributeError:
        exif = None

    if exif is None:
        return image

    exif = {
        PIL.ExifTags.TAGS[k]: v
        for k, v in exif.items()
        if k in PIL.ExifTags.TAGS
    }

    orientation = exif.get("Orientation", None)

    if orientation == 1:
        # do nothing
        return image
    elif orientation == 2:
        # left-to-right mirror
        return PIL.ImageOps.mirror(image)
    elif orientation == 3:
        # rotate 180
        return image.transpose(PIL.Image.ROTATE_180)
    elif orientation == 4:
        # top-to-bottom mirror
        return PIL.ImageOps.flip(image)
    elif orientation == 5:
        # top-to-left mirror
        return PIL.ImageOps.mirror(image.transpose(PIL.Image.ROTATE_270))
    elif orientation == 6:
        # rotate 270
        return image.transpose(PIL.Image.ROTATE_270)
    elif orientation == 7:
        # top-to-right mirror
        return PIL.ImageOps.mirror(image.transpose(PIL.Image.ROTATE_90))
    elif orientation == 8:
        # rotate 90
        return image.transpose(PIL.Image.ROTATE_90)
    else:
        return image

See also

Troubleshooting

AttributeError: module 'PIL.Image' has no attribute 'LINEAR'

AttributeError: module 'PIL.Image' has no attribute 'LINEAR'

This error occurs due to a version upgrade of the Pillow library. PIL.Image.LINEAR was removed as of Pillow 10.0.0.

Change it as follows:

  • PIL.Image.LINEAR → PIL.Image.BILINEAR (or Image.Resampling.BILINEAR)
  • PIL.Image.CUBIC → PIL.Image.BICUBIC (or Image.Resampling.BICUBIC)
  • PIL.Image.ANTIALIAS → PIL.Image.LANCZOS (or Image.Resampling.LANCZOS)

Or downgrade to an earlier version (9.5.0).

pip install Pillow==9.5.0

Favorite site

author Zer0 sitemap