VMware ESXi and vSphere Cluster Management

How to Rotate and Flip Images with Pillow

Learn how to rotate images by arbitrary or right angles and flip them horizontally or vertically with Python Pillow.

Pillow is a Python imaging library that provides an Image object and methods for changing images. In this lesson, you will rotate images by arbitrary angles, perform exact quarter-turn rotations, and flip images across horizontal or vertical axes.

You should already know basic Python variables, method calls, file paths, and installing packages with pip.

Install Pillow and open an image

Install Pillow with:

pip install Pillow

Import the Image module from Pillow, then use Image.open() to load a file. The returned image should be stored in a source variable. Transformation methods return new image objects, so keeping the source separate makes it easy to create several results from the same original.

from PIL import Image

image = Image.open("input.jpg")

Image.open() loads an image from a file path. Pillow commonly supports JPEG, PNG, GIF, WebP, and other formats. The file is opened when needed, so keep the source file available until you finish loading or processing it.

Rotate an image by an arbitrary angle

Image.rotate() creates a rotated copy of an image. Its angle argument is measured in degrees. Positive angles rotate counter-clockwise; use a negative angle for clockwise rotation.

from PIL import Image

image = Image.open("input.jpg")
rotated = image.rotate(45)
rotated.show()

In this example, rotated receives the returned image. The original image remains unchanged. The show() method opens a temporary local preview using an image viewer available on your system.

Rotate without cropping

By default, rotate() keeps the original canvas dimensions. When an image is rotated by an angle such as 45 degrees, its corners can extend beyond that canvas. Those parts are clipped.

Pass expand=True to enlarge the output canvas enough to contain the full rotated image:

from PIL import Image

image = Image.open("input.jpg")
rotated = image.rotate(45, expand=True)
rotated.save("rotated-expanded.jpg")

The newly exposed areas of the expanded canvas are filled with a background color. For many image modes, this defaults to black or another mode-dependent fill. If you need a particular background, Pillow also supports fill-color options in versions that provide them; check the installed Pillow version when exact fill behavior matters.

Rotate in 90-degree increments

For exact quarter-turn operations, use Image.transpose(). This method applies fixed orientation transformations. The constants Image.ROTATE_90, Image.ROTATE_180, and Image.ROTATE_270 represent rotations of 90, 180, and 270 degrees.

from PIL import Image

image = Image.open("input.jpg")

rotated_90 = image.transpose(Image.ROTATE_90)
rotated_180 = image.transpose(Image.ROTATE_180)
rotated_270 = image.transpose(Image.ROTATE_270)

rotated_90.show()
rotated_180.show()
rotated_270.show()

These operations are useful when an image must be turned by an exact right angle. A 90-degree or 270-degree result swaps the image's width and height. A 180-degree result keeps the same dimensions.

Flip or mirror an image

A flip reflects an image rather than turning it around by an angle. Pillow also performs flips with Image.transpose().

Image.FLIP_LEFT_RIGHT mirrors across the vertical axis, the imaginary line running from top to bottom. It swaps the left and right sides.

from PIL import Image

image = Image.open("input.jpg")
mirrored = image.transpose(Image.FLIP_LEFT_RIGHT)
mirrored.save("mirrored.jpg")

Image.FLIP_TOP_BOTTOM flips across the horizontal axis, the imaginary line running from left to right. It swaps the top and bottom sides.

flipped = image.transpose(Image.FLIP_TOP_BOTTOM)
flipped.show()

For example, text in a left-to-right mirror appears backward from left to right. A top-to-bottom flip places the top of the image at the bottom. Neither operation is the same as rotating by 90, 180, or 270 degrees.

Pillow rotation and flip operations

GoalPillow methodArgument or constantResult
Arbitrary-angle rotationrotate()An angle in degreesRotates counter-clockwise for positive angles
90-degree rotationtranspose()Image.ROTATE_90Turns the image by one quarter-turn
180-degree rotationtranspose()Image.ROTATE_180Turns the image upside down
270-degree rotationtranspose()Image.ROTATE_270Turns the image by three quarter-turns
Left-to-right mirrortranspose()Image.FLIP_LEFT_RIGHTSwaps the left and right sides across the vertical axis
Top-to-bottom fliptranspose()Image.FLIP_TOP_BOTTOMSwaps the top and bottom across the horizontal axis

Display and save transformed images

Use show() for a quick local preview:

rotated.show()

A preview is not a durable output file. Use save() when you need to keep the result:

rotated.save("rotated.jpg")
mirrored.save("mirrored.png")

Choose an output extension that matches the intended format, such as .jpg or .png. You can also explicitly provide a format when the filename does not identify one:

rotated.save("rotated-output", format="PNG")

Save to a new filename unless replacing the source is intentional. Keeping the original file separate allows you to retry a transformation and compare the result.

Rotation behavior comparison

ApproachBest use caseCanvas behaviorPotential issue
rotate(angle)Any angle when the original canvas is acceptableRetains the original dimensionsContent can be cropped at the corners
rotate(angle, expand=True)Arbitrary angles when the entire image must remain visibleExpands to fit the rotated imageUncovered areas receive a background fill
transpose(rotation constant)Exact 90-degree, 180-degree, or 270-degree turnsUses fixed orientation geometryIt is not intended for arbitrary angles

Complete examples

Rotate 45 degrees counter-clockwise

from PIL import Image

source = Image.open("input.jpg")
rotated_45 = source.rotate(45)
rotated_45.show()

Rotate 45 degrees and preserve the full image

from PIL import Image

source = Image.open("input.jpg")
rotated_45 = source.rotate(45, expand=True)
rotated_45.save("input-rotated-45.png")

Create 90, 180, and 270-degree outputs

from PIL import Image

source = Image.open("input.jpg")

quarter_turn = source.transpose(Image.ROTATE_90)
half_turn = source.transpose(Image.ROTATE_180)
three_quarter_turn = source.transpose(Image.ROTATE_270)

quarter_turn.save("input-90.jpg")
half_turn.save("input-180.jpg")
three_quarter_turn.save("input-270.jpg")

Mirror and flip

from PIL import Image

source = Image.open("input.jpg")

horizontal_mirror = source.transpose(Image.FLIP_LEFT_RIGHT)
vertical_flip = source.transpose(Image.FLIP_TOP_BOTTOM)

horizontal_mirror.save("input-mirror.jpg")
vertical_flip.save("input-flip.jpg")

Troubleshooting

Parts disappear after a 45-degree rotation

The rotated result is larger than the original canvas, so its corners were clipped. Use source.rotate(45, expand=True).

The rotation goes in the wrong direction

Pillow treats positive angles as counter-clockwise. Use a negative angle, such as source.rotate(-45), for clockwise rotation.

The result is mirrored instead of rotated

A flip constant was probably used. Use Image.ROTATE_90, Image.ROTATE_180, or Image.ROTATE_270 for fixed right-angle rotations.

The output does not appear where expected

show() only previews the image and does not save it. Call save() with an explicit destination filename.

Saving raises a format-related error

Check that the destination has a recognized extension or pass an explicit format. Also check the image mode: some formats do not support every mode, so you may need to convert the image before saving.

Summary

  • Use Image.open() to load an image and keep the source in its own variable.
  • Use rotate(angle) for arbitrary angles; positive angles rotate counter-clockwise.
  • Use expand=True when an arbitrary rotation must retain the full image.
  • Use transpose() with rotation constants for exact quarter-turns.
  • Use Image.FLIP_LEFT_RIGHT to mirror left to right and Image.FLIP_TOP_BOTTOM to flip top to bottom.
  • Use show() for previews and save() for persistent output.

For related Pillow image operations, continue with image rotation and transformation techniques.