恐竜本舗

エンジニアをしている恐竜の徒然日記です。

robotgo(Go) でカラーピッカーを作る

はじめに

Goでキーボードやマウス操作ができる robotgo というライブラリを知り、定常的に使っているカラーピッカーを自前で作り直したかったので今回挑戦してみました。

完成物

先に、出来上がったものはこちらです。

github.com

robotgo とは

github.com

キーボードやマウス操作、画面キャプチャなどをGoから扱えるライブラリです。 例えば、下記のようにマウス操作やスクリーン操作が行なえます。(サンプルコードより拝借)

package main

import (
  "github.com/go-vgo/robotgo"
)

func main() {
  // マウス操作
  robotgo.ScrollDir(10, "up")
  robotgo.ScrollDir(20, "right")

  robotgo.Scroll(0, -10)
  robotgo.Scroll(100, 0)

  robotgo.MilliSleep(100)
  robotgo.ScrollSmooth(-10, 6)

  robotgo.Move(10, 20)
  robotgo.MoveRelative(0, -10)
  robotgo.DragSmooth(10, 10)

  robotgo.Click("wheelRight")
  robotgo.Click("left", true)
  robotgo.MoveSmooth(100, 200, 1.0, 10.0)

  robotgo.Toggle("left")
  robotgo.Toggle("left", "up")

  // スクリーン操作
  x, y := robotgo.Location()
  fmt.Println("pos: ", x, y)

  color := robotgo.GetPixelColor(100, 200)
  fmt.Println("color---- ", color)

  sx, sy := robotgo.GetScreenSize()
  fmt.Println("get screen size: ", sx, sy)

  bit := robotgo.CaptureScreen(10, 10, 30, 30)
  defer robotgo.FreeBitmap(bit)

  img := robotgo.ToImage(bit)
  imgo.Save("test.png", img)

  num := robotgo.DisplaysNum()
  for i := 0; i < num; i++ {
    robotgo.DisplayID = i
    img1 := robotgo.CaptureImg()
    path1 := "save_" + strconv.Itoa(i)
    robotgo.Save(img1, path1+".png")
    robotgo.SaveJpeg(img1, path1+".jpeg", 50)

    img2 := robotgo.CaptureImg(10, 10, 20, 20)
    robotgo.Save(img2, "test_"+strconv.Itoa(i)+".png")
  }
}

カラーピッカーを作ってみる

robotgoを用いて、各種イベントに対して処理を登録していきます。 robotgo.EventHookというメソッドがあるので、これを用いてクリックイベントとKeyDownイベントを渡して処理の登録をしています。

fmt.Println("Please mouse left click to pick the color of current mouse position.")
fmt.Println("To pick the color of mouse positions, please enter ctrl+Shift+c.")
fmt.Println("To quit checking mouse event, please enter ctrl+Shift+q.")

// Stop event
robotgo.EventHook(hook.KeyDown, []string{"q", "shift", "ctrl"}, func(e hook.Event) {
    robotgo.EventEnd()
})

// Pick the color of event
robotgo.EventHook(hook.KeyDown, []string{"c", "shift", "ctrl"}, func(e hook.Event) {
    posx, posy := robotgo.GetMousePos()
    color := robotgo.GetPixelColor(posx, posy)
    robotgo.WriteAll(color)

    fmt.Println("Pick the color: ", color)
})

// Get color of current mouse position
robotgo.EventHook(hook.MouseDown, []string{}, func(e hook.Event) {
    posx, posy := robotgo.GetMousePos()
    color := robotgo.GetPixelColor(posx, posy)

    fmt.Println("pos-> ", posx, posy)
    fmt.Println("color-> ", color)
})

マウスクリックの度にカラーコードをクリップボードに取得されるのはモヤモヤするので、クリップボードへのコピーは処理を分けてます。 下記のようなメソッドを利用しています。

下記のように動きます。

$ go run main.go
Please mouse left click to pick the color of current mouse position.
To pick the color of mouse positions, please enter ctrl+Shift+c.
To quit checking mouse event, please enter ctrl+Shift+q.

// マウス左クリック時
pos->  968 703
color->  2d313b
// ctrl + shit + c 押下時
Pick the color:  efefef

robotgo を用いることで、さくっとマウスの現在地とそのカラーコードの取得ができました。 CLIだけだとどんな色を取得するか分かりにくく扱いづらいので、次回はもう少し改良していこうと思います。

参考

今回の制作にあたり、下記の記事も参考にさせて頂きました。

Robotgoでマウスポインタを自動で移動させる | かずさプログラマーの雑記帳