Skip to content

[PyQt5] click on the picture and get the pixel value of clicked position

Recently, when developing project that I am interested in, there is a demand for "click on the picture and get the pixel value". I thought this kind of demand was common, but I couldn't find any sample on the Internet. (Maybe the keywords I'm query are wrong.)

In order to let people who have the same needs may be able to refer to it in the future, I have recorded the methods I tried.

If you are interested in PyQt5, you can refer to the official guide: https://www.riverbankcomputing.com/static/Docs/PyQt5/index.html?highlight=qicon.

Or you can refer: [PyQt5] Tutorial(1) Install PyQt5 and print "Hello World!"


Solution

The method I think is very simple and rude, but I think it is quite effective.

  1. Rewrite the mousePressEvent() method of QLabel for knowing the position of we clicking
  2. Convert the QLabel image to PIL image, and we can get all pixel value of positions
  3. Correlate "the coordinates of the mouse click" with "the coordinates of PIL image"

After the above three steps, we can get the pixel value of the click coordinate, which is unexpectedly simple.

The only thing to be careful is that the coordinates of the PIL image and the coordinates of the mouse click must match together.

Suppose we have a 400x300 picture.

The coordinate x of the mouse click is [0-399], and the coordinate y is [0-299]; the pixel Index of PIL Image is [0-119999], so the conversion formula between the two should be as follows:

index = (y*400)+x

The following is my sample code:

# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PIL import ImageQt


class getColorLabel(QLabel):
    def __init__(self, widget):
        super(getColorLabel, self).__init__(widget)
        self.main = widget

    def mousePressEvent(self, event):
        self.main.get(event.pos())


class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.resize(800, 600)
        self.setWindowTitle('Drop Event Test')

        # Get Position
        self.label = getColorLabel(self)
        self.label.setGeometry(200, 250, 400, 300)
        self.label.setPixmap(QPixmap('test.png'))
        self.label.setScaledContents(True)

        # Display
        self.displayLabel = QLabel(self)
        self.displayLabel.setGeometry(300, 0, 200, 200)
        self.displayLabel.setStyleSheet('background-color: rgb(255, 255, 255);')

    def get(self, pos):
        index = pos.y()*self.label.size().width()+pos.x()
        image = ImageQt.fromqpixmap(self.label.pixmap())
        image = image.resize((self.label.size().width(), self.label.size().height()))
        image_data = image.getdata()
        r, g, b = image_data[index]
        self.displayLabel.setStyleSheet('background-color: rgb({},{},{});'.format(r, g, b))


if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())



Output:

I use a picture I have drawn freely as an example, and I can put the color of the clicked position on the label above.

click the upper left corner.
click the upper right corner
click the bottom left corner
clock the bottom right corner

The above is a note of my experience when I try to click on the location to get the pixel value.

Leave a Reply