BrettJ
BrettJ

Reputation: 1226

PIL - Images not rotating

I'm curious as to why my image is not rotating, it ends up in the same position every time.

img = Image.open(r'C:\Users\Brett\Downloads\testing.jpg')
exif_data = {
    TAGS[k]: v
    for k, v in img._getexif().items()
    if k in TAGS
}
print(exif_data['Orientation'])

That outputs a '6'

No matter how many degrees I tell the image to rotate it ends up in the same position.

if exif_data['Orientation'] == 6:
    img.rotate(90)

or

if exif_data['Orientation'] == 6:
    img.rotate(270) 

or

if exif_data['Orientation'] == 6:
    img.rotate(180)

I always end up with an image rotated 90 degrees counter-clockwise. Am I doing something obviously wrong?

Upvotes: 4

Views: 8022

Answers (3)

ML Rozendale
ML Rozendale

Reputation: 193

I had the same problem: If you rotate the image you should also modify the exif:

from PIL import Image
from exif import Image as Image2


def check_rotation(how, rotat):
    if "must be horizontal":
        if rotat == 6:
            return 1
        elif rotat == 8:
            return 3
        return None
    elif "must be vertical":
        if rotat == 3:                
            return 6
        elif rotat == 1:
            return 8
        return None
    else:
        raise "wrong how"

with Image.open(old_file, "r") as im:
    try:
        rotation = im._getexif()[274]
    except:
        raise "Failed to load exif with PIL"

    result = check_rotation("must be vertical", rotation)
    if result:
        print("rotated")
        # this ment the image must be rotated by 90 degrees and the exif_rotation will be updated by what the function returns
        im.transpose(Image.ROTATE_90)
        rotation = result  
    im.save(fp=f"{new_file}.jpg", format="JPEG", exif=im.info['exif'], quality=90)
    # here you see that it actually didn't rotate yet

with open(f"{new_file}.jpg", "rb") as im_file:
    imexif = Image2(im_file)
    if imexif.has_exif:
        # Updating exif rotation
        if imexif.get("orientation"):
            try:
                imexif.orientation = rotation
                # now it will rotate
            except:
                print("failed to modify EXIF orientation")
    # Writing the EXIF
    with open(f"{new_file}.jpg", 'wb') as updated_file:
        updated_file.write(imexif.get_file())

Upvotes: -1

that_roy
that_roy

Reputation: 104

In addition to the suggested answer above you could also just do the following.

if exif_data['Orientation'] == 6:
    img = img.rotate(90)

or

if exif_data['Orientation'] == 6:
    img = img.rotate(270)

or

if exif_data['Orientation'] == 6:
    img = img.rotate(180)

Additionally as mentioned above you may want to set the expand parameter, like the following to ensure that you don't run out of canvas for the rotated image.

if exif_data['Orientation'] == 6:
    img.rotate(180,expand=1)

Upvotes: 2

Stephen Rauch
Stephen Rauch

Reputation: 49814

From the (DOCS)

Image.rotate(angle, resample=0, expand=0, center=None, translate=None)

Returns a rotated copy of this image. This method returns a copy of this image, rotated the given number of degrees counter clockwise around its centre.

The image is not rotated in place. You need to store the image returned from rotate(). Maybe something like:

if exif_data['Orientation'] == 6:
    new_image = img.rotate(180)

Upvotes: 8

Related Questions