0

Here is the problem I've run into:

I have an image that has 3024 x 4032 in Dimensions, and usually just by looking at it, you know it's a vertical image, but it's not for whatever reasons. enter image description here

from PIL import Image

img = Image.open("xxx.jpg")
print(img.size)

It turns out to be (4032 x 3024) in dimensions, why is that?

In most of the cases, it prints out as expected, where dimensions has width as its first argument(img.size[o]), and height as its second argument(img.size[1]).

It looks like width and height aren't always in the right position? Or did I miss something?

2
  • I believe it's height first. A bunch of these image processing libraries/functions use (number of channels, height, width) as their image input format. Commented Oct 31, 2018 at 8:27
  • @SilverSlash, I guess the real question is, why does it output height as first, and some other time it outputs width as first? Commented Oct 31, 2018 at 8:37

2 Answers 2

2

Your picture might be rotated in exif tags.

Some mobile phones and cameras are "rotating" image when making a photo by this special field, not actually rotating pixel matrix of the image. So, in clever viewer programm you'll see dimensions of picture as it should be with applied exif rotation, but PIL will load it "as is" without any rotation tag involved.

So, you can check, if image was rotated, and then swap width and height:

from PIL import Image, ExifTags

img = Image.open("xxx.jpg")

def get_image_size(img):
    """
    The function return REAL size of image
    """

    # Lets get exif information in a form of nice dict:
    # It will be something like: {'ResolutionUnit': 2, 'Orientation': 6, 'YCbCrPositioning': 1}
    exif = {
        ExifTags.TAGS[k]: v
        for k, v in img._getexif().items()
        if k in ExifTags.TAGS
    }

    size = img.size

    # If orientation is horizontal, lets swap width and height:
    if exif.get("Orientation", 0) > 4:
        size = (size[1], size[0])

    return size

print(get_image_size(img))

Exif orientation is a number 1-8, that means the REAL image orientation

Info about it could be found here: http://sylvana.net/jpegcrop/exif_orientation.html

Sign up to request clarification or add additional context in comments.

2 Comments

Dude, you're right! I've tested your code and it did return the real image orientation! Wow! Thank you.
Also, I've updated code, so, if "Orientation" tag isn't set in your image, there would be not erros with "Null > 4" comparision types inconsistence
1

From the Pillow docs for Image.size

Image size, in pixels. The size is given as a 2-tuple (width, height). Type: (width, height)

7 Comments

Thanks for providing the Pillow docs, so it confuses me even more, because as I said, when I xxx.size, it is clearly prints out the other way around, so its height first, and width.
I don't see anything confusing. Obviously this scrrenshot comes from software that has them the other way around. Or always showing the smaller number first? In any case you said you expect it to be vertical (i.e. portait mode) but it's not. Image.size returns (4032 x 3024), so it clearly is width>height, i.e. landscape mode - exactly what you have. Maybe you should ask what your other software shows first.
@moomoochen I guessed! It's a phone! So, look at my answer :)
@MihanEntalpo: Still strange. OP claims all images are portrait shots, yet Pillow "rotates" the image size so that they appear landscape. If all this is true and your explanation is correct, Pillow should return same tuple for all 6 images.
I just waiting while @moomoochen test my function on the files, and comment, does it work or no :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.