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

ICC Profile not saved for TIF files #5225

Closed
Crubert-digit opened this issue Jan 25, 2021 · 7 comments · Fixed by #5321
Closed

ICC Profile not saved for TIF files #5225

Crubert-digit opened this issue Jan 25, 2021 · 7 comments · Fixed by #5321
Labels

Comments

@Crubert-digit
Copy link

Crubert-digit commented Jan 25, 2021

When loading an image from an array(image opened with cv2, skimage, etc.) and then saving it in .tif format, the icc_profile is not saved. For example:

import cv2
from PIL import Image, ImageCms

profile = ImageCms.getOpenProfile("AdobeRGB.icm")

img_cv2 = cv2.imread("original.png")
img_pil = Image.fromarray(cv2.cvtColor(img_cv2, cv2.COLOR_BGR2RGB))
img_pil.save("result_cv2_to_pil_tif.tif", icc_profile=profile.tobytes())

However, when doing the same for a ".png" file the icc_profile is saved

img_pil.save("result_cv2_to_pil_tif.tif", icc_profile=profile.tobytes())

I solved it adding the icc_profile to the info attribute prior saving the image:

img_pil.info['icc_profile'] = profile.tobytes()
img_pil.save("result_cv2_to_pil_tif.tif")

It seems a bug in the save method when the file format is .tif, as it not considers adding the icc_profile to the output image if it was not previously in the info attribute.

I haven't tested it with other file formats.

@radarhere radarhere added the TIFF label Jan 25, 2021
@radarhere radarhere changed the title Icc Profile not saved for TIF Files ICC Profile not saved for TIF Files Jan 25, 2021
@radarhere radarhere changed the title ICC Profile not saved for TIF Files ICC Profile not saved for TIF files Jan 25, 2021
@GvdBend
Copy link

GvdBend commented Jan 26, 2021

Hi Crubert-digit,
I justed wanted to add that I'm having the same problem. For me the ".tobytes()" give me an error as well "AttributeError: 'bytes' object has no attribute 'tobytes'". If I save the images without going to bytes it works for saving it, but the colors of the image do not change (for .tif format).

I checked my images color spaces before and after the convert (.jpg and .tif). Both of them shows after the convert that there is a Adobe RGB profile, but only the .jpg shows the correct colors.

Does anyone know how to fix this problem?

@Crubert-digit
Copy link
Author

Hi GvdBend,

Are you opening the profile file with ImageCms.getOpenProfile("AdobeRGB.icm")?? It seems you're trying to convert to Bytes an object which is already Bytes. I use the tobytes() method to convert the profile file to the icc_profile bytes format after opening it with ImageCms.

For the TIF files try assigning the profile on the info attribute prior saving it (I'm assuming the profile variable already has the icc profile loaded and it is a Bytes object):

image.info['icc_profile'] = profile

@GvdBend
Copy link

GvdBend commented Jan 27, 2021

Hi Crubert-digit,

Sorry, I'm quite new to Python and I indeed didn't use the "ImageCms.getOpenProfile("AdobeRGB.icm")". Now when I try to use your code it gives me the following error : 'PIL.ImageCms.PyCMSError: cannot open profile file'. My understanding is that I haven't created the AdobeRGB profile yet, as it does not standard exist in Pillow?

I've checked the website and tried to read more in to the getOpenProfile and buildTransformFromOpenProfiles, but can't really figure out what to do. Could you please explain to me what you did. Thanks in advance!

@Crubert-digit
Copy link
Author

Hi GvdBend,

ImageCms.getOpenProfile("AdobeRGB.icm") is opening a file in my path called 'AdobeRGB.icm' which contains the icc profile, so actually the method is:
ImageCms.getOpenProfile(file_path)

@GvdBend
Copy link

GvdBend commented Jan 27, 2021

Hi Crubert-digit,

Thanks to you I made it work, thank you!

@radarhere
Copy link
Member

However, when doing the same for a ".png" file the icc_profile is saved

img_pil.save("result_cv2_to_pil_tif.tif", icc_profile=profile.tobytes())

This is confusing - I presume you meant to write "result_cv2_to_pil_tif.png" in your code example.

@radarhere
Copy link
Member

I've created #5321 to resolve this.

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

Successfully merging a pull request may close this issue.

3 participants