Search code examples
pythonopencvimage-processingpython-imaging-librarytiff

Converting a TIFF Image saved with a transparency can't be converted to JPEG image in Python


I am trying to solve a problem in Python where I am needing to convert TIFF images to JPEGs. I have tried using Pillow as well as OpenCV to do this but keep getting errors when I try to convert a TIFF image that has the transparency saved on it. If I save the TIFF and remove the transparency it saves the JPEG successfully. The transparency has to remain on the TIFF. Does anyone know of a solution for this issue? If I could find a way to even save the TIFF without the transparency via a Python script, save as a JPEG, and then delete the TIFF without the transparency that would work too. Any help here would be greatly appreciated. Below are examples of code I have tried that have failed:

import os
from PIL import Image

os.chdir('S:/DAM/Test/Approved/')
# for root, dirs, files in os.walk('S:/DAM/Test/Approved'):
for root, dirs, files in os.walk('.'):
    for name in files:

        if name.endswith('.tif'):

            filename = os.path.join(root, name)
            print('These are the files: ', filename)
            # img = Image.open(filename).convert('RGB')
            img = Image.open(filename)
            print('image is open', filename)
            img = img.convert('RGB')
            print('image should be converted: ', filename)
            imageResize = img.resize((2500, 2500))
            print('image should be resized: ', filename)
            imageResize.save(filename[:-4]+'.jpg', 'JPEG')
            print('image should be saved as a jpeg: ', filename)

Here is the error I get when Python tries to open the TIFF with transparency using Pillow:

Exception has occurred: UnidentifiedImageError
cannot identify image file '.\\Beauty Images\\XXX.tif'
  File "U:\Python files\image_conversion2.py", line 22, in <module>
    img = Image.open(filename)

When I run this code using OpenCV it fails on the same image as well:

img = cv2.imread('S:/DAM/Test/Approved/Beauty Images/XXX.tif')
cv2.imwrite('S:/DAM/Test/Approved/Beauty Images/XXX.jpg', img)

Here is the error I get with this code:

OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp:715: error: (-215:Assertion failed) !_img.empty() in function 'cv::imwrite'
  File "U:\Python files\img_convert_new.py", line 19, in <module>
    cv2.imwrite('S:/DAM/Test/Approved/Beauty Images/XXX.tif', img)

Solution

  • Thanks to @cgohlke the solution was found! The solution is as follows using imagecodecs. The fullpath variable is the root + '/' + file of the source path.

    for root, subdirs, files in os.walk(src):
       for file in files:
          fullpath = (root + '/' + file)
    
    from imagecodecs import imread, imwrite
    from PIL import Image
    
    imwrite(fullpath[:-4] + '.jpg', imread(fullpath)[:,:,:3].copy()) # <-- using the imagecodecs library function of imread, make a copy in memory of the TIFF File.
                        # The :3 on the end of the numpy array is stripping the alpha channel from the TIFF file if it has one so it can be easily converted to a JPEG file.
                        # Once the copy is made the imwrite function is creating a JPEG file from the TIFF file.
                        # The [:-4] is stripping off the .tif extension from the file and the + '.jpg' is adding the .jpg extension to the newly created JPEG file.
                        img = Image.open(fullpath[:-4] + '.jpg') # <-- Using the Image.open function from the Pillow library, we are getting the newly created JPEG file and opening it.
                        img = img.convert('RGB') # <-- Using the convert function we are making sure to convert the JPEG file to RGB color mode.
                        imageResize = img.resize((2500, 2500)) # <-- Using the resize function we are resizing the JPEG to 2500 x 2500
                        imageResize.save(fullpath[:-4] + '.jpg') # <-- Using the save function, we are saving the newly sized JPEG file over the original JPEG file initially created.