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

Support 16-bit grayscale ImageQt conversion #5856

Merged
merged 4 commits into from Dec 14, 2021

Conversation

cmbruns
Copy link
Contributor

@cmbruns cmbruns commented Nov 29, 2021

Steps to reproduce:

from PIL import Image, ImageQt

image = Image.open("test.tif")  # test.tif is a 16-bit grayscale image
imageqt = ImageQt.ImageQt(image)

Expected behavior: A valid QImage is created.

Behavior without this code change: ValueError: unsupported image mode 'I;16'

I verified that a valid QImage is created with this change. Sorry I cannot share the test image I am using.

@radarhere radarhere changed the title Support 16-bit grayscale ImageQt conversion. Support 16-bit grayscale ImageQt conversion Nov 29, 2021
@radarhere radarhere added Needs Tests Qt Qt for Python, PyQt, PySide and removed Needs Tests labels Nov 29, 2021
@radarhere
Copy link
Member

When you say that you created 'a valid QImage', did the output visually match what it should?

If I take demo code from https://www.pythonguis.com/faq/adding-images-to-pyqt5-applications/, modify it slightly and run with your PR, I just get black.

import sys
from PIL import Image, ImageQt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel

# hopper("I;16")
im = Image.open("Tests/images/hopper.ppm")
im = im.convert("I").convert("I;16")

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        label = QLabel(self)
        pixmap = QPixmap(ImageQt.toqpixmap(im))
        label.setPixmap(pixmap)
        self.setCentralWidget(label)
        self.resize(pixmap.width(), pixmap.height())

app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

Screen Shot 2021-12-01 at 7 44 30 pm

@cmbruns
Copy link
Contributor Author

cmbruns commented Dec 1, 2021

@radarhere it's not exactly black, it's just really really dark. Presumably im.convert("I").convert("I;16") leaves the values in the range 0 to 255, which is a very small slice of the full 16-bit 0-65535 range. Your example looks better if you change line 8 to

im = im.convert("I").convert("I;16").point(lambda i: i * 255)

i16_hopper_test

@radarhere
Copy link
Member

I'll move my example into tests.

diff --git a/Tests/test_imageqt.py b/Tests/test_imageqt.py
index 08cab9976..48f9f370f 100644
--- a/Tests/test_imageqt.py
+++ b/Tests/test_imageqt.py
@@ -46,7 +46,27 @@ def test_image():
         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"))
+        im = ImageQt.ImageQt(hopper("I;16"))
+
+        import sys
+        from PyQt5.QtGui import QPixmap
+        from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel
+
+        class MainWindow(QMainWindow):
+
+            def __init__(self):
+                super(MainWindow, self).__init__()
+
+                label = QLabel(self)
+                pixmap = QPixmap.fromImage(im)
+                label.setPixmap(pixmap)
+                self.setCentralWidget(label)
+                self.resize(pixmap.width(), pixmap.height())
+
+        app = QApplication(sys.argv)
+        w = MainWindow()
+        w.show()
+        app.exec_()
 
 
 def test_closed_file():

The above code still shows the black, or 'really really dark' image.

I'm just saying that while this PR may not generate any errors, it is also not producing correct images. That's likely not a problem you've caused - Pillow does not have very good handling of I;16 in general.

@radarhere
Copy link
Member

I've created cmbruns#1 to fix the 'really really dark' image.

@radarhere radarhere force-pushed the cmbruns/grayscale-16-bit-qimage branch from 037354e to 768c189 Compare December 14, 2021 19:39
@radarhere radarhere added the automerge Automatically merge PRs that are ready label Dec 14, 2021
@mergify mergify bot merged commit f4c010b into python-pillow:main Dec 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge Automatically merge PRs that are ready Qt Qt for Python, PyQt, PySide
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants