デスクトップ画面からQRコードをスキャンする方法


我々の生活の中で、我々は通常QRコードをスキャンするスマートフォンを取る.しかし、我々がコンピュータに取り組んでいるとき、Smartphoneはウェブページに現れるQRコードをスキャンするための最も良い選択でないかもしれません.つの理由は、モニタ画面から撮影された写真はQRコード認識を妨げるモアレのパターンを持っている.もう一つの理由は、直接ウェブサイトを開くためのURLなどのPCにデコードされた情報を使用することがあります.この記事は、デスクトップ画面でQRコードの認識を容易にするためにPythonとのシンプルなツールを実装します.

インストール
必要なPythonパッケージはPIL , OpenCV , Dynamsoft Barcode Reader and Qt .
python3 -m pip install pillow opencv-python dbr pyside2

バーコードSDKライセンス
DynamsoftのバーコードSDKの機能のロックを解除するには30-day free trial license .

画面からQRコードをスキャンする
以来、私はGUI barcode reader Python、OpenCVとDynamsoftバーコードリーダーのQtを使用して、残りの部分は、画面のスナップ機能を追加することです.インスパイアドhttps://github.com/harupy/snipping-tool , スクリーンショット機能を実装する手順を学びました.
  • カスタムQtウィジェットを作成し、画面の上に置きます.
  • 選択した領域をpaintEvent() マウスを動かしながら機能します.
  • マウスがリリースされるとPIL.ImageGrab.grab() 選択した領域のイメージを取得します.

  • イベントをスナップするためのボタンを追加する
    私たちはdesign.ui Qtの作成者のファイルとスナップイベントをトリガするための2つのボタンを追加します.

    ファイルを保存して再コンパイルするdesign.ui to design.py :
    pyside2-uic design.ui -o design.py
    
    インapp_advanced.py , つの新しいボタンをすぐに認識する必要があります.スロット関数に接続します.
    self.ui.pushButton_area.clicked.connect(self.snipArea)
    self.ui.pushButton_full.clicked.connect(self.snipFull)
    

    カスタムQtウィジェットを作成する
    クリエイトアSnippingTool.py カスタムのQtウィジェットを作成するファイルです.
    import numpy as np
    import cv2
    from PIL import ImageGrab
    from PySide2 import QtWidgets, QtCore, QtGui
    from PySide2.QtCore import Qt
    
    class SnippingWidget(QtWidgets.QWidget):
        is_snipping = False
    
        def __init__(self, parent=None, app=None):
            super(SnippingWidget, self).__init__()
            self.parent = parent
            self.setWindowFlags(Qt.WindowStaysOnTopHint)
    
            self.screen = app.primaryScreen()
            self.setGeometry(0, 0, self.screen.size().width(), self.screen.size().height())
            self.begin = QtCore.QPoint()
            self.end = QtCore.QPoint()
            self.onSnippingCompleted = None
    
        def start(self):
            SnippingWidget.is_snipping = True
            self.setWindowOpacity(0.3)
            QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
            self.show()
    
    ウィジェットのサイズはスクリーン解像度と同じであるべきです.primaryScreen() 関数.
    次にマウスイベントを処理します.
    def mousePressEvent(self, event):
        self.begin = event.pos()
        self.end = self.begin
        self.update()
    
    def mouseMoveEvent(self, event):
        self.end = event.pos()
        self.update()
    
    def mouseReleaseEvent(self, event):
        SnippingWidget.is_snipping = False
        QtWidgets.QApplication.restoreOverrideCursor()
        x1 = min(self.begin.x(), self.end.x())
        y1 = min(self.begin.y(), self.end.y())
        x2 = max(self.begin.x(), self.end.x())
        y2 = max(self.begin.y(), self.end.y())
    
        self.repaint()
        QtWidgets.QApplication.processEvents()
        self.close()
    
    マウスが動いている間、我々は選択された領域を示すために長方形を描きますpaintEvent() 機能
    def paintEvent(self, event):
        if SnippingWidget.is_snipping:
            brush_color = (128, 128, 255, 100)
            lw = 3
            opacity = 0.3
        else:
            self.begin = QtCore.QPoint()
            self.end = QtCore.QPoint()
            brush_color = (0, 0, 0, 0)
            lw = 0
            opacity = 0
    
        self.setWindowOpacity(opacity)
        qp = QtGui.QPainter(self)
        qp.setPen(QtGui.QPen(QtGui.QColor('black'), lw))
        qp.setBrush(QtGui.QColor(*brush_color))
        rect = QtCore.QRectF(self.begin, self.end)
        qp.drawRect(rect)
    

    スクリーンイメージを取る
    PILは画面から画像を取り込むためのPythonライブラリです.マウスをリリースした後、我々は、矩形の座標に基づいて選択された領域のスクリーンショットを取る.
    img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
    
    try:
        img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    except:
        img = None
    
    フルスクリーンイメージを取るのは簡単です.
    img = ImageGrab.grab(bbox=(0, 0, self.screen.size().width(), self.screen.size().height()))
    

    アプリケーションウィンドウを非表示にして表示する
    ウィジェットが準備ができたら、ボタンをクリックしてイベントを呼び出すことができます.注意:画面を妨害するのを避けるために、アプリケーションウィンドウをsnippingウィジェットを起動する前に最小化し、snippingが完了した後に復元します.
    def onSnippingCompleted(self, frame):
        self.setWindowState(Qt.WindowMaximized)
        if frame is None:
            return 
    
        frame, self._results = self._barcodeManager.decode_frame(frame)
        self.showResults(frame, self._results)
    
    def snipArea(self):
        self.setWindowState(Qt.WindowMinimized)
        self.snippingWidget.start()    
    
    def snipFull(self):
        self.setWindowState(Qt.WindowMinimized)
        self.snippingWidget.fullscreen() 
    

    スクリーンQRリーダーをテストします

  • バーコード認識プログラムを実行します.
    python3 app_advanced.py
    
  • Google検索QR code .

  • をクリックしますSelect Area ボタンは、検索エンジンによって返さQRコード(1つまたは複数)をスキャンします.

    また、ワンクリックでフルスクリーンのバーコード認識を行うことができます.

  • ソースコード
    https://github.com/yushulx/python-gui-barcode-reader