Skip to content

[PyQt5] 點擊圖片並取得該位置的像素值

最近在開發自己感興趣的專案時,有了『點選圖片取得像素值』這樣的需求。這樣的需求我本來以為很常見,但查詢網路上後意外發現居然找不到什麼 Sample Code。(題外話,我剛打完這段字,突然有了興趣,再次丟 StackOverFlow,這次真的找到答案了,不過跟我想要的解答不太一樣)

為了讓以後有同樣需求的人或許能夠參考一下,我整理了下我嘗試出的辦法,讓各位見笑了。

如果對於 PyQt5 有興趣,可以參閱官方的指南: https://www.riverbankcomputing.com/static/Docs/PyQt5/index.html?highlight=qicon

或者是我之前寫過的 PyQt5 系列 的筆記。


解決辦法

我想的方法非常地簡單粗暴,但是我覺得還頗有效的。

  1. 重寫 QLabel 的 mousePressEvent(),讓我們知道點擊的座標
  2. 將 QLabel 的圖片轉成 PIL 的 Image,得到每個座標的像素值
  3. 將『滑鼠點擊的座標』跟『PIL Image 該座標』對應起來

經過上方簡單的三個步驟,我們就可以得到點擊座標的像素值了,其實意外簡單。

唯一需要小心的是,PIL Image 的座標跟滑鼠點擊的座標必須 Match 在一起才行。

假設我們有個 400 x 300 的圖片:

滑鼠點擊的座標 x 是 [0-399]、座標 y 則是 [0-299];PIL Image 的像素 Index 則是 [0-119999] ,故兩者之間的轉換公式應如下:

index = (y*400)+x

以下是我的 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:

我使用有了隨手畫的一張圖來作範例,可以將點選位置的顏色放到上面的 Label。

點選左上角。
點選右上角
點選左下角
點選右下角

以上就是我嘗試點選位置得到像素值的心得筆記。

Leave a Reply