3
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout
from PyQt5.QtGui import QPixmap, QImage
import numpy as np
import sys

def print_np():
    app = QApplication(sys.argv)

    win = QWidget()
    label = QLabel()

    img = np.ones((500, 500))
    qImg = QPixmap(QImage(img.data, img.shape[0], img.shape[1], QImage.Format_Indexed8))
    label.setPixmap(qImg)

    vbox = QVBoxLayout()
    vbox.addWidget(label)
    win.setLayout(vbox)
    win.show()

    sys.exit(app.exec_())

In this code, I am trying to display 2d np array on QtWindow.

I am expecting to see a white square, but I keep getting a weird display as below.

I believe its because wrong QImage.Format (data type), so I tried every option but didn't help.

https://srinikom.github.io/pyside-docs/PySide/QtGui/QImage.html#PySide.QtGui.QImage

Should I change np array to jpg or png first, as examples in documentation?

enter image description here

4
  • 1
    Why have you removed the #import statements? It makes your code impossible to run and it's therefore harder to assist you. Commented Feb 13, 2020 at 8:53
  • Are you hoping to display colours in your image? If so, it needs to be of shape 500,500,3 to accommodate 3 RGB channels and have type RGB888. If you only want black/white/greys, your shape is correct but you need to tell Qt is is greyscale. Commented Feb 13, 2020 at 9:06
  • 2
    Your array is float64, when you needed int8: img = np.ones((500, 500), dtype=dtype=np.uint8). And maybe you also want the RGB version img = np.ones((3, 500, 500) ... Commented Feb 13, 2020 at 9:10
  • ` img = np.zeros((500, 500, 3), dtype=np.uint8) qImg = QPixmap( QImage(img.data, img.shape[0], img.shape[1], QImage.Format_RGB888)) label.setPixmap(qImg) ` Both np.zeros and ones give me a black image. Could you explain why? Commented Feb 13, 2020 at 9:33

1 Answer 1

4

There are a couple of issues:

  • Your dtype needs to be np.uint8 when you create your Numpy image array
  • Your format needs to be QImage.Format_RGB888
  • Your pixels need to bigger than 0 or 1 to show up, the full range is 0..255

So, with that in mind:

#!/usr/bin/env python3

from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout
from PyQt5.QtGui import QPixmap, QImage
import numpy as np
import sys

def main():
    app = QApplication(sys.argv)

    win = QWidget()
    label = QLabel()

    img = np.zeros((500, 500, 3), dtype=np.uint8)
    # Turn up red channel to full scale
    img[...,0] = 255
    qImg = QPixmap(QImage(img.data, img.shape[0], img.shape[1], QImage.Format_RGB888))
    label.setPixmap(qImg)

    vbox = QVBoxLayout()
    vbox.addWidget(label)
    win.setLayout(vbox)
    win.show()

    sys.exit(app.exec_())

main()

enter image description here

++ (to convert 2D image as black vs white)

img = np.zeros((500, 500), dtype=np.uint8)
img[250:, :] = 255

qImg = QPixmap(QImage(img.data, img.shape[0], img.shape[1], QImage.Format_Grayscale8))

It will create a window

enter image description here

Keywords: Python, Qt, QImage, QPixmap, image processing.

Sign up to request clarification or add additional context in comments.

3 Comments

@Sean Rather than QImage.Format_Indexed8, you should probably use QImage.Format_Grayscale8 to be sure of tones.
I edited once more, btw thank you so much for your answer!
Cool, and thanks also to @Demi-Lune Good luck with your project and remember, questions (and answers) are free, so come back if you get stuck.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.