質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

6969閲覧

できるだけ軽い画面キャプチャ方法

katakana

総合スコア7

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

1クリップ

投稿2019/08/03 14:24

編集2019/08/04 11:56

前提・実現したいこと

ゲームのBOTを作成しています。
画面上の敵を攻撃し、体力が減ったら回復を行い、魔力に余裕があればスキルを使用し、ミニマップを確認しながら移動し…というもので、画面全体を何度もキャプチャする必要があります。

Pythonにて、PillowのImageGrabを用いて試作してみたのですが、負荷が大きく、あまり実用的なものにはなりませんでした。
(敵の探査に一番負荷がかかり、その次に重いのが画面キャプチャなので、キャプチャ部分をどうにかしたいというのが、今回の質問の意図です)
そこで現在、Win32apiを用いてプログラム全体を作り直している最中でして、画面の取得はPrintWindowで行っております。

本題ですが、より負荷の少ない画面キャプチャ方法(関数名、ライブラリ名など)をご存じでしたらご教示いただければ幸いです。
(キャプチャというか、画面の特定の座標の画素値を低負荷で取得できる方法はないのでしょうか?)
手法の名前だけなどでも構いませんので、回答よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

Windows 10
Python 3.7.1

Python以外の言語の使用可否:可
上記のBOTはバックグラウンドで動作することが必須なため、それが可能な言語であれば変更可能です。
Win32apiで実現可能と思われるため、大抵の言語に変更が可能です。
追記での申告となり申し訳ありません。(03:45, 2019年8月4日)

パケット解析やメモリスキャン等が困難な状況なため、画像処理的な手段で作成しようと考えております。
後から何度も追記してしまい申し訳ありません。(16:57, 2019年8月4日)

謝辞

ImageGrabより負荷の軽い方法を示してくださったZuishin様をベストアンサーとさせていただきます。1ドットを監視すれば行える、体力自動回復、スキルの自動使用部分の負荷を下げることができました。
PrtScを使用する方法は、私の技術力不足により、どのようにすればバックグラウンドの画面を取得できるか分かりませんでした、申し訳ありません。
また、Teratailが初めてで、至らない投稿をしてしまい、申し訳ありませんでした。編集・追記依頼を記入してくださった方々にも御礼を申し上げます。
皆様、ありがとうございました。

最後になりますが、敵の探査のような大きめの範囲の画素値を取得しなければいけない場合に、これまではPrintWindowで画面を取得した後Numpyのasarray関数でarrayに変換して使用していたのですが、frombuffer関数を使用したほうが高速で、およそ3/5の時間で変換できることが分かりました。
備忘録がてら記載させていただきます。

metainfo👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

atata0319

2019/08/03 18:05 編集

情報が少なすぎて回答が難しいです。使用している OS の種類、Python 以外の言語の使用可否、使用可能であればその言語の情報について追記ください。その場合、タグも編集していただけると回答が集まりやすいかと思います。ImageGrab 以上の処理性能を Python だけで達成できると考えおられるなら PyQt をお勧めします。それ以上の性能を達成するのであれば、Python だけでは難しいかもしれません。
katakana

2019/08/03 18:59 編集

atata0319様 回答ありがとうございます。追記を行いました。至らない状態の質問を投稿してしまい、申し訳ありませんでした。Pythonは負荷を考慮しない場合、一番楽に実装できそうだと考え使用しましたがやはり難しいのですね。ベクトル化すれば大丈夫だと楽観視しておりました。
退会済みユーザー

退会済みユーザー

2019/08/04 02:18

ざくっとみたかんじ MMORPG のBOT作成のようだけど画像なんてキャプチャする必要がないよ。 普通は通信されるデータを解析する。
katakana

2019/08/04 07:58

asahina1979様 回答ありがとうございます。今回、パケット解析やメモリスキャン等が困難な状況なため、画像処理的な手段で行うつもりでおります。後出しでの申告となり申し訳ありません。
guest

回答2

0

ベストアンサー

https://stackoverflow.com/a/1997875

python

1from ctypes import windll 2 3user32 = windll.LoadLibrary("user32.dll") 4gdi32 = windll.LoadLibrary("gdi32.dll") 5 6def getrgb(x, y, hdc=user32.GetDC(None)): 7 bgr = gdi32.GetPixel(hdc, x, y) 8 return bgr.to_bytes(3, "little") 9 10r, g, b = getrgb(10, 10) 11print("R={r}, G={g}, B={b}".format(r=r, g=g, b=b))

投稿2019/08/04 02:02

編集2019/08/04 02:17
YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/08/04 03:29

これ、軽いんですか? 見た限りむちゃくちゃ重そうですが。
YouheiSakurai

2019/08/04 04:07

手元の環境で比較してみましたが、まぁまぁだと思いますよ。 Timer("tuple(getrgb(10, 10))", globals=globals()).timeit(1000) -> 16.673903699999983 Timer("ImageGrab.grab(bbox=(10, 10, 11, 11)).getcolors()[0][1]", globals=globals()).timeit(1000) -> 55.71892229999992
Zuishin

2019/08/04 04:13

1 ドットなら 1/3 から 1/4 の時間で処理できるということですね。
katakana

2019/08/04 08:02

YouheiSakurai様 コードまで用意していただき、ありがとうございます。画素値を取得する関数がwin32apiに用意されていたのですね(無知で申し訳ありません)。早速実装してみたいと思います。
guest

0

PrtScキーを送出するとかではどうでしょう

投稿2019/08/03 23:35

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katakana

2019/08/04 08:05

y_waiwai様 回答ありがとうございます。PrtScはバックグラウンド(他のウィンドウに隠れた状態)の画面を取得できると思っていなかったため、盲点でした。実装してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問