From 6aca23cfa32889f9dae83f5374d216662cb7de8e Mon Sep 17 00:00:00 2001 From: Christopher Bruns Date: Sun, 28 Nov 2021 19:34:14 -0800 Subject: [PATCH 1/4] Support 16-bit grayscale ImageQt conversion. --- src/PIL/ImageQt.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/PIL/ImageQt.py b/src/PIL/ImageQt.py index e142f1f277e..f10de325853 100644 --- a/src/PIL/ImageQt.py +++ b/src/PIL/ImageQt.py @@ -108,7 +108,7 @@ def align8to32(bytes, width, mode): converts each scanline of data from 8 bit to 32 bit aligned """ - bits_per_pixel = {"1": 1, "L": 8, "P": 8}[mode] + bits_per_pixel = {"1": 1, "L": 8, "P": 8, "I;16": 16}[mode] # calculate bytes per line and the extra padding if needed bits_per_line = bits_per_pixel * width @@ -167,6 +167,8 @@ def _toqclass_helper(im): elif im.mode == "RGBA": data = im.tobytes("raw", "BGRA") format = qt_format.Format_ARGB32 + elif im.mode == "I;16": + format = qt_format.Format_Grayscale16 else: if exclusive_fp: im.close() From b1cc094f57b8dcc445dbf11e5f077f097940b8ad Mon Sep 17 00:00:00 2001 From: Christopher Bruns Date: Mon, 29 Nov 2021 16:54:09 -0800 Subject: [PATCH 2/4] Add 16-bit grayscale test --- Tests/test_imageqt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/test_imageqt.py b/Tests/test_imageqt.py index 53b1fef7c6d..a7947b0a2de 100644 --- a/Tests/test_imageqt.py +++ b/Tests/test_imageqt.py @@ -42,7 +42,7 @@ def checkrgb(r, g, b): def test_image(): - for mode in ("1", "RGB", "RGBA", "L", "P"): + for mode in ("1", "RGB", "RGBA", "L", "P", "I;16"): ImageQt.ImageQt(hopper(mode)) From e87745d9ec34e76fbe236bd3a6ff1225762e04ad Mon Sep 17 00:00:00 2001 From: Christopher Bruns Date: Mon, 29 Nov 2021 19:38:57 -0800 Subject: [PATCH 3/4] Check if installed Qt version supports Format_Grayscale16 --- Tests/test_imageqt.py | 5 ++++- src/PIL/ImageQt.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Tests/test_imageqt.py b/Tests/test_imageqt.py index a7947b0a2de..08cab9976b2 100644 --- a/Tests/test_imageqt.py +++ b/Tests/test_imageqt.py @@ -42,8 +42,11 @@ def checkrgb(r, g, b): def test_image(): - for mode in ("1", "RGB", "RGBA", "L", "P", "I;16"): + for mode in ("1", "RGB", "RGBA", "L", "P"): ImageQt.ImageQt(hopper(mode)) + qt_format = ImageQt.QImage.Format if ImageQt.qt_version == "6" else ImageQt.QImage + if hasattr(qt_format, "Format_Grayscale16"): # Qt 5.13+ + ImageQt.ImageQt(hopper("I;16")) def test_closed_file(): diff --git a/src/PIL/ImageQt.py b/src/PIL/ImageQt.py index f10de325853..8970314d9ae 100644 --- a/src/PIL/ImageQt.py +++ b/src/PIL/ImageQt.py @@ -167,7 +167,7 @@ def _toqclass_helper(im): elif im.mode == "RGBA": data = im.tobytes("raw", "BGRA") format = qt_format.Format_ARGB32 - elif im.mode == "I;16": + elif im.mode == "I;16" and hasattr(qt_format, "Format_Grayscale16"): # Qt 5.13+ format = qt_format.Format_Grayscale16 else: if exclusive_fp: From 768c189a2999553d91b271546e01df96c2dd1078 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 14 Dec 2021 10:13:09 +1100 Subject: [PATCH 4/4] Correct image by scaling pixels --- Tests/test_imageqt.py | 14 ++++++++++---- src/PIL/ImageQt.py | 2 ++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Tests/test_imageqt.py b/Tests/test_imageqt.py index 08cab9976b2..589cb5a210a 100644 --- a/Tests/test_imageqt.py +++ b/Tests/test_imageqt.py @@ -2,7 +2,7 @@ from PIL import ImageQt -from .helper import hopper +from .helper import assert_image_similar, hopper pytestmark = pytest.mark.skipif( not ImageQt.qt_is_installed, reason="Qt bindings are not installed" @@ -42,11 +42,17 @@ def checkrgb(r, g, b): def test_image(): - for mode in ("1", "RGB", "RGBA", "L", "P"): - ImageQt.ImageQt(hopper(mode)) + modes = ["1", "RGB", "RGBA", "L", "P"] qt_format = ImageQt.QImage.Format if ImageQt.qt_version == "6" else ImageQt.QImage if hasattr(qt_format, "Format_Grayscale16"): # Qt 5.13+ - ImageQt.ImageQt(hopper("I;16")) + modes.append("I;16") + + for mode in modes: + im = hopper(mode) + roundtripped_im = ImageQt.fromqimage(ImageQt.ImageQt(im)) + if mode not in ("RGB", "RGBA"): + im = im.convert("RGB") + assert_image_similar(roundtripped_im, im, 1) def test_closed_file(): diff --git a/src/PIL/ImageQt.py b/src/PIL/ImageQt.py index 8970314d9ae..db8fa0fa9f9 100644 --- a/src/PIL/ImageQt.py +++ b/src/PIL/ImageQt.py @@ -168,6 +168,8 @@ def _toqclass_helper(im): data = im.tobytes("raw", "BGRA") format = qt_format.Format_ARGB32 elif im.mode == "I;16" and hasattr(qt_format, "Format_Grayscale16"): # Qt 5.13+ + im = im.point(lambda i: i * 256) + format = qt_format.Format_Grayscale16 else: if exclusive_fp: