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

Brightness clipped on I;16 images loaded from png #5967

Closed
flagadum opened this issue Jan 17, 2022 · 3 comments · Fixed by #6112
Closed

Brightness clipped on I;16 images loaded from png #5967

flagadum opened this issue Jan 17, 2022 · 3 comments · Fixed by #6112

Comments

@flagadum
Copy link

flagadum commented Jan 17, 2022

What did you do?

  • Open a 16bit greyscale image from a png file
  • Paste that image into another 16bit greyscale image (I;16)

What did you expect to happen?

The pasted image should be kept the same

What actually happened?

The bright pixels got clipped to middle grey (32767 ?)

Proposed workaround?

Immediately after loading png, convert the image to array, then back to image again.

What are your OS, Python and Pillow versions?

  • OS: MacOS 10.15
  • Python: 3.9.10
  • Pillow: 9.0.0
from PIL import Image
import numpy

# Let's create a white 16bit square 
img1 = Image.new("I;16",(256,256),(65535))

# Let's save this square as png and open it again
if True :    # if False: The bug does not happen
	img1.save("test.png")
	img1 = Image.open("test.png")

if False :    # If True: Bug workaround: Convert image to array and back to image again
	(sizeu,sizev) = img1.size
	img1 = Image.fromarray(numpy.array(img1.getdata()).astype(numpy.uint16).reshape((sizev,sizeu)))

# We check that the loaded square is white
img1.show()

# But we might already see that something is wrong here
print(img1.histogram())

# Let's paste this square in another 16bit image
img2 = Image.new("I;16",(288,288),(0))
img2.paste(img1,(16,16,272,272))

# Is the pasted square white or grey???
img2.show()
@radarhere radarhere changed the title Image.crop clips brightness on 16bit greyscale images loaded from png file Brightness clipped on 16bit greyscale images loaded from png Jan 17, 2022
@radarhere radarhere changed the title Brightness clipped on 16bit greyscale images loaded from png Brightness clipped on I;16 images loaded from png Jan 29, 2022
@radarhere
Copy link
Member

radarhere commented Mar 2, 2022

Currently, Pillow opens I;16 PNGs as I. See #3041 or #3796

from PIL import Image

im = Image.new("I;16", (1, 1))
im.save("test.png")
reloaded = Image.open("test.png")
print(reloaded.mode)  # I

So a workaround would be to save it as a TIFF instead.

@radarhere
Copy link
Member

radarhere commented Mar 5, 2022

Another workaround would be to create img2 as "I" rather than "I;16".

@radarhere
Copy link
Member

I've created PR #6112 to resolve this particular scenario, by fixing incorrect clipping when the "I" mode PNG was converted to match the "I;16" image you were pasting it on.

However, Pillow will still clip the values of the 32-bit "I" mode when converting to the 16-bit "I;16" mode. This scenario is only fixed by my PR because you are using white. If you try this with other images, I expect you will find a problem.

So resolving this situation more generally can be either part of #3796 or #3159.

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

Successfully merging a pull request may close this issue.

2 participants