Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I stop PIL from swapping height/width when rotating an image 90°?

I am using PIL to rotate an image. This works in general, except when I rotate the image exactly 90° or 270°, in which case the x and y measurements swap. That is, given this image:

>>> img.size
(93, 64)

If I rotate it by 89° I get this:

>>> img.rotate(89).size
(93, 64)

And by 91° I get this:

>>> img.rotate(91).size
(93, 64)

But if I rotate it by either 90° or 270°, I find the height and width swapped:

>>> img.rotate(90).size
(64, 93)
>>> img.rotate(270).size
(64, 93)

What's the correct way to prevent this?

like image 622
larsks Avatar asked Jul 08 '15 21:07

larsks


People also ask

How do I rotate an image 90 degrees in Python?

To rotate an image by an angle with Python Pillow, you can use rotate() method on the Image object. rotate() method rotates the image in counter clockwise direction.

How do I rotate an image in PIL?

PIL.Image.Image.rotate() method – This method is used to rotate a given image to the given number of degrees counter clockwise around its centre. Parameters: image_object: It is the real image which is to be rotated. angle: In degrees counter clockwise.

How do you rotate an image in Python?

The imutils. rotate() function is used to rotate an image by an angle in Python.

How do you change the height and width of an image in Python?

To resize an image, you call the resize() method on it, passing in a two-integer tuple argument representing the width and height of the resized image. The function doesn't modify the used image; it instead returns another Image with the new dimensions.


1 Answers

I'm hoping someone comes up with a more graceful solution, but this seems to work for now:

img = Image.open('myimage.pbm')

frames = []
for angle in range(0, 365, 5):
    # rotate the image with expand=True, which makes the canvas
    # large enough to contain the entire rotated image.
    x = img.rotate(angle, expand=True)

    # crop the rotated image to the size of the original image
    x = x.crop(box=(x.size[0]/2 - img.size[0]/2,
               x.size[1]/2 - img.size[1]/2,
               x.size[0]/2 + img.size[0]/2,
               x.size[1]/2 + img.size[1]/2))

    # do stuff with the rotated image here.

For angles other than 90° and 270° this results in the same behavior as you get if you set expand=False and don't bother with the crop operation.

like image 163
larsks Avatar answered Oct 05 '22 10:10

larsks