12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PythonでWindowsのスニッピングツールらしきものを実装してみた

Last updated at Posted at 2017-06-11

概要

PythonでWindowsのスニッピングツールらしきもの(ドラッグ&ドロップで選択した領域を画像として保存するプログラム)を実装してみました.やや強引な実装なのかもしれませんが,ご容赦下さい.

Youtubeにプログラムが動作しているところをUPしたので,是非一度ご覧下さい.
https://www.youtube.com/watch?v=e2zePSUGwaA

動機

前回投稿した「Pythonでタイピングゲームをプレイしてみた」のプログラムを作成した際,スクリーン上でキャプチャしたい領域のピクセル座標を,直感的かつ動的に取得する方法を模索していたところ,Windowsのスニッピングツールのような形式が最適だと思ったので,Pythonで実装してみようと思いました.

環境

OS : Windows10
Python Version : 3.5.3

使用した主なライブラリ

PyQt5, Pillow, OpenCV

プログラムの動作

main.py
# -*- coding: utf-8 -*-

import sys
from PyQt5 import QtWidgets, QtCore, QtGui
import tkinter as tk
from PIL import ImageGrab, Image
import matplotlib.pyplot as plt
import numpy as np
import cv2

class MyWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        root = tk.Tk()
        screen_width = root.winfo_screenwidth()
        screen_height = root.winfo_screenheight()
        self.setGeometry(0,0,screen_width, screen_height)
        self.setWindowTitle("")
        self.setWindowOpacity(0.3)
        QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.begin = QtCore.QPoint()
        self.end = QtCore.QPoint()

        print("Capture the screen...")
        self.show()

    def paintEvent(self, event):
        qp = QtGui.QPainter(self)
        qp.setPen(QtGui.QPen(QtGui.QColor("black"), 3))
        qp.setBrush(QtGui.QColor(128, 128, 255, 128))
        qp.drawRect(QtCore.QRect(self.begin, self.end))       
        
    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):
        self.end = event.pos()
        self.close()
           
        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())
        
        img = ImageGrab.grab(bbox=(x1,y1,x2,y2))
        img.save("capture.png")
        img = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2RGB)

        cv2.imshow('Captured Image', img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MyWidget()
    window.show()
    app.aboutToQuit.connect(app.deleteLater)
    sys.exit(app.exec_())


  1. PyQt5を使用して,背景を透過させたGUIをスクリーン全体を覆うように配置.
  2. マウス関連のイベントリスナーを用いて,GUI上でのドラッグに合わせてピクセル座標を取得し,それをもとに長方形を描画.
  3. ドロップ時,GUIを消去した後,PillowImageGrabを用いて,選択した領域をキャプチャし画像として保存.
  4. OpenCVを用いて,取得した画像を表示.

応用

  1. スクリーンキャプチャを起点とするプログラムと組み合わせる.
  2. 取得した座標を用いて何かする.

まとめ

PythonでWindowsのスニッピングツールらしきものを実装することができた.

12
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?