タグ別アーカイブ: MapleStory

[C#]スクリーンキャプチャいろいろ

MapleStoryのスクリーンショットを取得しようとしたんだけど、どうも環境によって動作が違って、上手くいかなかった。

最初に試したのが、Win32APIのPrintWindow()
これだと、マルチディスプレイだろうと、画面外に飛び出していようと、他ウィンドウで隠れていようと正確にキャプチャ出来るんだけど、ホスト側の64bit7でしかちゃんと動いてくれなくて、VMのXP,7ではMapleStoryのキャプチャーは出来なかった。理由はわからないけど・・・。

msRect.***はそれぞれ座標が入ってる

 
 
 
 
次に試したのがBitBlt
これは前に邪魔なウィンドウとかがあると、それはそのまま映り込んでしまうから正常に動作しない、最前面にウィンドウがあれば、非アクティブ状態でも取得出来る。
ホストの7と、ゲストのXPは正常動作したんだけど、VMの7だと不思議な動作だった。
非アクティブ状態と、クリックボタン押し続けてる間は取得出来る。でも、MapleStoryをアクティブにすると上手く動作しなくなる。
動画撮ったんだけど、こんな感じ。

うーん・・・不思議。

コードコピペだけど。

 
 
 
 

全部の環境で上手く行ったのがこれ。
同じくbitbltなんだけど、全体のスクリーンショットを取得してから必要な部分だけ切り抜くようにしてみたら上手く行った。
違いはなんだろう?
マルチディスプレイには対応できなくなってしまった。

printWindowが使えれば一番良いんだけどー

[C#]画面上の数字を読み取る

文字だったら、OCR使えば良いと思うんだけど、数字なら10種類しかないわけだし、1pixelずつ比較していったほうが確実だと思う。

MapleStoryのスクリーンショットを取得して、HP、MP、経験値、レベルの4つの値を取得したい。

mapleHPbar

またOpenCVに頼ることにした。
C#にも、GetPixelっていうのがあるんだけど、処理速度が遅すぎる。
OpenCVは早くて簡単で便利!できることも多いし、コード量も少なくて済む、良い事尽くめ。

取得したい文字が白なので、画像をグレースケール化して、文字に使われてる色の中で、一番黒に近い色を探す。
結果、220,220,220くらいが一番暗い色だったので、220以下の色を全て0,0,0の真っ黒に変更、それよりも明るい色を255,255,255の真っ白に変更
っていう、2値化の処理をCv.Thresholdでやってる。
この処理でimgに2値化された画像が入るので、そこから数字を読み取ってやる。
読み取る方法は、画像を1ピクセルずつ、縦に見ていって、白の数を数えて、その組み合わせで数字を判断してやる。
わけあって1行目は拾ってないので、2行目から7行目の6ピクセル分を縦に取得して、numArrExpに、1列毎にデータを追加していく。
それをtpExpNumberに渡す。

numberPixel
白の個数が0だったら次へ
白が存在すれば、その列の白の数と、次の列とか、次の次の列とかの白の個数からその数字が何なのか判断して、strに追加していく。
ループが終わったら、strをintにparseしてreturn。
HP,MP,レベルに関してもだいたい同じような処理でやってる。
数字しかないので間違いなく判断してくれる。文字だったらOCR使うしかないね。不安だけど。

そんな感じで作ったのがExpEfficiency

ExpEfficiency

テスト中に撮ったから、タイトル部分がForm1になってたりするけど、こんな感じのUIにした。
レベルアップまでの時間と、予想時刻、後1時間あたりに換算した経験値量もつけたほうがわかりやすいかなー。

定期メールレポート機能付けてみたから、外出中でも定期的に経験値上昇状況が送られてくる。もし増えてなかったら探知機で飛ばされたか落ちたか死んだか。
そうなったらスマホでリモート操作して狩りに戻したりね。

今のところ、x64の実機7proと、x86のVMXPproで動作確認出来てる。
x86VM7Homeがどうしても動かない。今週中には何とかしたい。