Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TIFF orientation tag handled differently from most other software when loading G4 TIFF files #4053

Closed
ailintom opened this issue Sep 7, 2019 · 7 comments · Fixed by #4063
Labels
Projects

Comments

@ailintom
Copy link

ailintom commented Sep 7, 2019

Most image software handles TIFF orientation tags (tag 274) differently from Pillow when loading binary G4 TIFF images. This means that only images having the orientation tag == 1 (The 0th row represents the visual top of the image, and the 0th column represents the visual left-hand side) are loaded correctly (in the same way as in other software), other images should be corrected manually.
I am not sure whether Pillow regards the orientation tags while other software ignores or vice versa. At least they are loaded transposed.
I use Pillow-6.1.0 with Python 3.8 on Windows.

I've developed the following procedure in my script to load TIFF files correctly (basically I only have files with orientation==8 from my office copier machine, so I have not tested other orientations). I think this something similar should be part of the TIFFImagePlugin

from PIL import Image
from tkinter import filedialog, Tk
ORIENTATION = 274
root = Tk()
root.withdraw()
file_selected = filedialog.askopenfilename()
srcim = Image.open(filename)
orientation = srcim.tag[ORIENTATION][0]
format = os.path.splitext(filename)[1]
if format.lower() in [".tif", ".tiff"]:
     try:
        if orientation == 8:
            srcim = srcim.transpose(Image.ROTATE_90)
        elif orientation == 3:
            srcim = srcim.transpose(Image.ROTATE_180)
        elif orientation == 6:
            srcim = srcim.transpose(Image.ROTATE_270)
        elif orientation == 2:
            srcim = srcim.transpose(Image.FLIP_LEFT_RIGHT)
        elif orientation == 4:
            srcim = srcim.transpose(Image.FLIP_TOP_BOTTOM)
        elif orientation == 5:
            srcim = srcim.transpose(Image.ROTATE_90).transpose(Image.FLIP_LEFT_RIGHT)
        elif orientation == 7:
            srcim = srcim.transpose(Image.ROTATE_270).transpose(Image.FLIP_LEFT_RIGHT)
     except:
          print("Can't detect orientation")
@ailintom ailintom changed the title TIFF orientation tag ignored when loading G4 TIFF files TIFF orientation tag handled differently from most other software when loading G4 TIFF files Sep 7, 2019
@radarhere
Copy link
Member

Hi. In Pillow 6.0, ImageOps.exif_tranpose was added -

Pillow/src/PIL/ImageOps.py

Lines 523 to 530 in 1e3c2c9

def exif_transpose(image):
"""
If an image has an EXIF Orientation tag, return a new image that is
transposed accordingly. Otherwise, return a copy of the image.
:param image: The image to transpose.
:return: An image.
"""

So you should be able to simplify your code down to -

from PIL import Image, ImageOps
from tkinter import filedialog, Tk
root = Tk()
root.withdraw()
file_selected = filedialog.askopenfilename()
srcim = Image.open(filename)
srcim = ImageOps.exif_transpose(src_im)

If you're asking why this is not applied automatically, the answer would be that ImageOps.exif_transpose has not always been a part of Pillow, and we value backwards compatibility highly.

@ailintom
Copy link
Author

ailintom commented Sep 7, 2019

Hi, thanks for the reply. No, exif_transpose does not help. I mean TIFF tags, not the EXIF, it is a different thing. Try loading this file with PIL
It shows upright in most graphic software, but PIL displays it rotated, because it disregards the TIFF 274 tag (orientation)
test1.zip

@ailintom
Copy link
Author

ailintom commented Sep 8, 2019

Here is the updated procedure for correcting TIFF file orientation:

from PIL import Image
TIFFTAG_ORIENTATION = 274
def correct_tiff(srcim):
    try:
        orientation = srcim.tag[TIFFTAG_ORIENTATION][0]
        

        if orientation == 2:
            srcim = srcim.transpose(Image.FLIP_LEFT_RIGHT)
        elif orientation == 3:
            srcim = srcim.transpose(Image.ROTATE_180)            
        elif orientation == 4:
            srcim = srcim.transpose(Image.FLIP_TOP_BOTTOM)
        elif orientation == 5:
            srcim = srcim.transpose(Image.TRANSPOSE)
        elif orientation == 6:
            srcim = srcim.transpose(Image.ROTATE_270)            
        elif orientation == 7:
            srcim = srcim.transpose(Image.TRANSVERSE)
        elif orientation == 8:
            srcim = srcim.transpose(Image.ROTATE_90)       
    except:
        pass
    return srcim

and a small test script with a full set of test files (tiff G4 and uncompressed)
attached.

tiff orientation test.zip

@radarhere
Copy link
Member

Thanks for all that. Could any of those images be be added to the test suite, under the Pillow license?

@ailintom
Copy link
Author

ailintom commented Sep 8, 2019

Yes, both code snippets and the images are absolutely free to use under any license.

@radarhere
Copy link
Member

Okay. I've created #4062 to add an ImageOps.auto_transpose method. See what you think.

@radarhere
Copy link
Member

I've now created #4063 to transpose TIFF images on load instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Pillow
  
Closed
Development

Successfully merging a pull request may close this issue.

2 participants