作業自動化に使えるPyAutoGUI紹介　【スクショ・指定画像位置検知】

## はじめに
前回に引き続き，自作RPAツールとして利用できる「PyAutoGUI」について紹介していきます．

「マウス操作」「キーボード操作」のコマンドはこちら
→ [作業自動化に使えるPyAutoGUI紹介①](https://qiita.com/suipy/items/a50c95293126c41bcca0)

## PyAutoGUIとは
Pythonスクリプトでマウスとキーボードを制御して，「マウス操作の自動化」や「キーボード入力の自動化」を実現します．

## 動作環境
- Python 3.12.0
- PyAutoGUI 0.9.54

PyAutoGUIはpipを使用してインストールできます．
```
pip install pyautogui
```

## コマンド紹介
### 【メッセージボックス機能】
- alert()
テキストと1つのOKボタンを持つシンプルなメッセージボックスを表示します．クリックされたボタンのテキストを返します．
```python
import pyautogui as pag

pag_alert = pag.alert(text='pyautogui', title='qiita', button='OK')
print(pag_alert) # 出力は「OK」
```
[実行結果]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/517e407b-64fe-5a76-b7e5-4c05752f4983.png)

---
- verify()
メッセージボックスにOKボタンとキャンセルボタンを表示します．ボタンの数とテキストはカスタマイズできます．クリックされたボタンのテキストを返します．
```python
import pyautogui as pag

pag_confirm = pag.confirm(text='pyautogui', title='qiita', buttons=['OK', 'Cancel'])
print(pag_confirm) # 出力はOKボタンを押すと「OK」，Cancelボタンを押すと「Cancel」
```
[実行結果]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/657dc201-e2cb-c4d8-7c9f-15a1d661a5d7.png)

---
- prompt()
テキスト入力のメッセージボックスと，「OK」と「キャンセル」ボタンを表示します．OKが押された場合は入力されたテキスト，キャンセルがクリックされた場合はNoneを返します．
```python
import pyautogui as pag

pag_prompt = pag.prompt(text='pyautogui', title='qiita' , default='')
print(pag_prompt) # OKを押した場合，入力ボックスに入力した文字列，Cancelを押した場合，Noneを返す
```
[実行結果]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/e8c88c29-aaa7-6d41-1949-41a732d54cd5.png)
prompt関数のdefaultに文字列を入力すると，メッセージボックス起動後，入力ボックス内に設定した文字列が初期状態として記入されます．文字列を設定しなければ，空欄の状態で起動します．

---
- password()
テキスト入力が可能なメッセージボックスと，「OK」「キャンセル」ボタンを表示します．UI上では入力された文字は*と表示されます．OKが押された場合は入力されたテキスト，キャンセルがクリックされた場合はNoneを返します．
```python
import pyautogui as pag

pag_password = pag.password(text='pyautogui', title='qiita', default='', mask='*')
print(pag_pasword) # OKを押した場合，入力ボックスに入力した文字列，Cancelを押した場合，Noneを返す
```
[実行結果]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/ff30b422-130a-50b0-6659-4eb5e364d6f7.png)

↓文字列入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/78cd2f5a-5ea3-83d6-85fb-2f3df6abfc2c.png)

password関数もprompt関数同様のdefault設定になります．
文字列入力後の伏せ字は第四引数のmaskで変更できます．

---
### 【スクリーンショット機能】

- screenshot()
screenshot()を呼び出すと，Imageオブジェクトが返されます．ファイル名の文字列を渡すと，スクリーンショットをファイルに保存し，Image オブジェクトとして返します．
```python
import pyautogui as pag

im1 = pag.screenshot()
im2 = pag.screenshot(r"C:\Qiita\test.png")
```
画面全体のスクリーンショットを取得したくない場合は，オプションでregionキーワード引数を指定することもできる．キャプチャする領域のleft、top、width、heightの4整数のタプルを渡して設定する．
```python
import pyautogui as pag

im = pag.screenshot(region=(0, 0, 300, 400))
```

---
### 【Locate機能】
画像ファイルがあれば，画面上の何かを視覚的に見つけることができます．例えば，下図の「ブラウザを閉じるボタン」の画像があれば，ブラウザがどの位置に存在していても「閉じるボタン」の座標を取得することができ，click()などと併用して操作を自動化することが可能です．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/eec089eb-a013-201a-aa48-04a87fbd8fd2.png)

---
- locateOnScreen()
locateOnScreen()は指定した画像がスクリーンに表示されている場合，座標を取得します．戻り値は4変数のタプル（left, top, width, height）です．スクリーン上に指定画像と同じ絵が見つからない場合，ImageNotFoundExceptionを発生させます．

locateOnScreen()で取得したタプルをcenter()に渡すことで，この領域の中心のX座標とY座標を得ることができます．

```python
import pyautogui as pag

location_closeButton = pag.locateOnScreen('close.png')
location_closeButton
# -> Box(left=1400, top=500, width=50, height=40)
location_closeButton[0]
# -> 1400 
location_closeButton.left
# -> 1400

point_closeButton = pag.center(location_closeButton)
point_closeButton
# -> Point(x=1425, y=520)
point_closeButton[0]
# -> 1425
point_closeButton.x
# -> 1425

# 指定した画像と同じ絵をクリック
button_x, button_y = point_closeButton
pag.click(button_x, button_y) # 閉じるボタンがあった場所の中央をクリック
pag.click('close.png') # 閉じるボタンがあった場所の中央をクリックするショートカット版
```

オプションのconfidenceキーワード引数は，関数が画面上の画像の位置を特定する精度を指定します．confidenceキーワードが機能するためには，<INS>**OpenCV**</INS>がインストールされている必要があります．

```python
import pyautogui as pag

location_closeButton = pag.locateOnScreen('close.png', confidence=0.9)
```

---
- locateCenterOnScreen()
文字通り，locateOnScreen()とcenter()を組み合わせたものです．
```python
import pyautogui as pag

x, y = pag.locateCenterOnScreen('close.png')
pag.click(x, y)
```

---
- locateAllOnScreen()
locateAllOnScreen()は指定した画像がスクリーン上にある場合，それら全ての座標(4変数のタプル)を返します．forループで使用したり，listに渡すことができます．
```python
import pyautogui as pag

for pos in pag.locateAllOnScreen('someButton.png')
    print(pos)

list(pyautogui.locateAllOnScreen('someButton.png'))
```

locate関数は実行に長い時間を要することがあります．
これを避けるためには，<INS>region引数を設定して画面全体の検索ではなく一部のみの検索にすることです．</INS>

---
- グレースケールマッチング
オプションとして，locate関数にgrayscale=Trueを渡すことで，若干（約30%程度）のスピードアップを図ることができます．画像やスクリーンショットの色が減色され，検索速度が速くなりますが，誤判定を引き起こす可能性があるため注意が必要です．
```python
import pyautogui as pag

location_closeButton = pag.locateOnScreen('close.png', grayscale=True)
```

---
- ピクセルマッチング
スクリーンショットのピクセルのRGBカラーを取得します．
```python
import pyautogui as pag

im = pag.screenshot()
im.getpixel((100, 200))
# -> (130, 135, 140)
```

または，1つの関数としてpixel() PyAutoGUI関数を呼び出します．
```python
import pyautogui as pag

pix = pyautogui.pixel(100, 200)
pix
# -> RGB(red=130, green=135, blue=140)
pix[0]
# -> 130
pix.red
# -> 130
```

pixelMatchesColor()を使用して，1つのピクセルが指定されたピクセルと一致するかを判定できます．戻り値はTrue/Falseです．
```python
import pyautogui as pag

pag.pixelMatchesColor(100, 200, (130, 135, 140)) # 座標(100, 200)のRGB値が(130, 135, 140)と同じか
# -> True
pag.pixelMatchesColor(100, 200, (0, 0, 0)) # 座標(100, 200)のRGB値が(0, 0, 0)と同じか
# -> False
```
オプションのtoleranceキーワード引数は，赤，緑，青の各値が一致しながらどの程度変化するかを指定します．
```python
import pyautogui as pag

pag.pixelMatchesColor(100, 200, (130, 135, 144))
# -> True
pag.pixelMatchesColor(100, 200, (140, 125, 134))
# -> False
pag.pixelMatchesColor(100, 200, (140, 125, 134), tolerance=10)
# -> True
```