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

Do not down-convert if image is LA when showing with PNG format #3869

Merged
merged 3 commits into from Jun 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions Tests/test_image_mode.py
Expand Up @@ -26,6 +26,17 @@ def test_sanity(self):
self.assertEqual(m.basemode, "L")
self.assertEqual(m.basetype, "L")

for mode in ("I;16", "I;16S",
"I;16L", "I;16LS",
"I;16B", "I;16BS",
"I;16N", "I;16NS"):
m = ImageMode.getmode(mode)
self.assertEqual(m.mode, mode)
self.assertEqual(str(m), mode)
self.assertEqual(m.bands, ("I",))
self.assertEqual(m.basemode, "L")
self.assertEqual(m.basetype, "L")

m = ImageMode.getmode("RGB")
self.assertEqual(m.mode, "RGB")
self.assertEqual(str(m), "RGB")
Expand Down
11 changes: 6 additions & 5 deletions Tests/test_imageshow.py
Expand Up @@ -18,18 +18,19 @@ def test_register(self):
ImageShow._viewers.pop()

def test_show(self):
class TestViewer:
class TestViewer(ImageShow.Viewer):
methodCalled = False

def show(self, image, title=None, **options):
def show_image(self, image, **options):
self.methodCalled = True
return True
viewer = TestViewer()
ImageShow.register(viewer, -1)

im = hopper()
self.assertTrue(ImageShow.show(im))
self.assertTrue(viewer.methodCalled)
for mode in ("1", "I;16", "LA", "RGB", "RGBA"):
im = hopper(mode)
self.assertTrue(ImageShow.show(im))
self.assertTrue(viewer.methodCalled)

# Restore original state
ImageShow._viewers.pop(0)
Expand Down
14 changes: 11 additions & 3 deletions src/PIL/ImageMode.py
Expand Up @@ -48,9 +48,17 @@ def getmode(mode):
modes["La"] = ModeDescriptor("La", ("L", "a"), "L", "L")
modes["PA"] = ModeDescriptor("PA", ("P", "A"), "RGB", "L")
# mapping modes
modes["I;16"] = ModeDescriptor("I;16", "I", "L", "L")
modes["I;16L"] = ModeDescriptor("I;16L", "I", "L", "L")
modes["I;16B"] = ModeDescriptor("I;16B", "I", "L", "L")
for i16mode in (
"I;16",
"I;16S",
"I;16L",
"I;16LS",
"I;16B",
"I;16BS",
"I;16N",
"I;16NS",
):
modes[i16mode] = ModeDescriptor(i16mode, ("I",), "L", "L")
# set global mode cache atomically
_modes = modes
return _modes[mode]
14 changes: 5 additions & 9 deletions src/PIL/ImageShow.py
Expand Up @@ -63,16 +63,12 @@ class Viewer(object):
def show(self, image, **options):

# save temporary image to disk
if image.mode[:4] == "I;16":
# @PIL88 @PIL101
# "I;16" isn't an 'official' mode, but we still want to
# provide a simple way to show 16-bit images.
base = "L"
# FIXME: auto-contrast if max() > 255?
else:
if not (
image.mode in ("1", "RGBA") or (self.format == "PNG" and image.mode == "LA")
):
base = Image.getmodebase(image.mode)
if base != image.mode and image.mode != "1" and image.mode != "RGBA":
image = image.convert(base)
if image.mode != base:
image = image.convert(base)

return self.show_image(image, **options)

Expand Down