# Python : Media : pillow \[ [src](https://github.com/python-pillow/Pillow/) | [docs](https://pillow.readthedocs.io/en/stable/) | [API](https://pillow.readthedocs.io/en/stable/reference/) ] Friendly fork of PIL (Python Imaging Library). (Author died.) ## Overview The core image library is designed for fast access to data stored in a few basic pixel formats. - extensive file format support - efficient internal representation - powerful image processing capabilities - create thumbnails, convert between file formats, print images - point operations, filtering with a set of built-in convolution kernels, color space conversions - image resizing, rotation and arbitrary affine transforms - histogram method to generate image stats — can be used for automatic contrast enhancement When you open a file, the file header is read to determine the file format and extract things like mode, size, and other properties required to decode the file, but the raster data isn't loaded and decoded until and unless necessary. This means that opening an image file is a fast operation, which is independent of the file size and compression type. Coordinates (0,0) refer to the implied pixel corners. The center of a pixel addressed as (0, 0) actually lies at (0.5, 0.5). #### Metadata You can attach auxiliary information to an image using the `info` dict. How such information is handled when loading and saving image files is up to the file format handler. Most handlers add properties to the `info` attribute when loading an image, but ignore it when saving images. > [!EXIF Orientation] > A common element of the info attribute for JPG and TIFF images is the EXIF orientation tag. This is an instruction for how the image data should be oriented. For example, it may instruct an image to be rotated by 90 degrees, or to be mirrored. To apply this information to an image, `exif_transpose()` can be used. ## Cheatsheet ```python # imports from PIL import Image, ImageDraw, ImageEnhance, ImageFilter, ImageOps, ImagePalette, ImageSequence, ImageTk, PSDraw # constants Image.Transpose. FLIP_LEFT_RIGHT FLIP_TOP_BOTTOM ROTATE_90 (counter-clockwise) ROTATE_180 ROTATE_270 (counter-clockwise) TRANSPOSE TRANSVERSE ImageFilter. BLUR CONTOUR DETAIL EDGE_ENHANCE, EDGE_ENHANCE_MORE EMBOSS FIND_EDGES SHARPEN SMOOTH, SMOOTH_MORE # opening im = Image.open( "filename" | fileobj ) # PngImagePlugin.PngImageFile -or- with Image.open( "filename" ) as im: ... # attributes im.filename "a.png" im.format "PNG" # None if not read from file im.has_transparency_data False im.info { str: <record_type> } # ex: PngImagePlugin.iTXt (subclass of str) im.is_animated False im.mode "RGB" im.n_frames 1 im.palette None | ImagePalette.ImagePalette im.size ( 512, 512 ) # methods im.filter( ImageFilter.DETAIL ) # BLUR, DETAIL, ... im.resize( (x,y) ) # returns resized copy im.rotate( int ) # returns rotated copy; int -> degrees counter-clockwise im.save( "filename" ) # output format based on file extension im.show() # save image to tmp file and call external display utility (for debugging) im.thumbnail( (x,y) ) # like resize(), but modifies existing image # regions region = im.crop( box ) # box = ( left, upper, right, lower ) (0,0 -> upper-left corner) region = region.transpose( Image.Transpose.ROTATE_180 ) im.paste( region, box ) # doesn't require modes to match; can take transparency mask (0..255) # RECIPE: merging two images im = Image.new( "RGBA", ( w, h ) ) im.paste( im1 ) im.paste( im2, ( w, h ) ) ``` > [!NOTE] File Format > When an image is opened from a file, only that instance of the image is considered to have the format. Copies of the image will contain data loaded from the file, but not the file itself, meaning that it can no longer be considered to be in the original format. So if copy() is called on an image, or another method internally creates a copy of the image, then any methods or attributes specific to the format will no longer be present. The fp (file pointer) attribute will no longer be present, and the format attribute will be None. ## INBOX ``` expand = True # allow for size changes resulting from actions like rotate GIF: TODO ICO: TODO JPEG: TODO APNG: TODO WebP: TODO plus many more PDF: TODO (write-only, as binary PDF 1.4) PNG EXIF data can be read; not guaranateed to be present until load() open() sets: info.chromaticity info.gamma info.srgb info.transparency info.text = { tEXt, zTXt, iTXt } save( ...options... ) Other interesting modules: ImageDraw - 2D + text ImageOps - common / useful operations ExifTags PIL.PngImagePlugin.PngInfo ```