0

全体として、CopyFromScreen()方法iを使用すると、(以前にキャプチャされた)画像を、その特定の画面から実際にキャプチャされた原因と同じ画像と比較することができました。

または、より単純に、たとえば、デスクトップから切り取って、その場所(ポイント)とそのサイズ(size(h、w))を参照するテキストファイルとともに画像として保存したアイコン

したがって、File.WriteAllBytes(byte [] made it .bar)を介してcaptured.barをファイル+ cuptured.txtに、場所とサイズを参照して取得すると、コピーがhddに保存され、その場所とサイズがtxtになります。(私はすべてのコードを投稿する必要はありませんでしたが、それはうまくいくので、誰かがそれを必要とするなら..私は気軽に共有します)

これを実現する方法は、私が作成した方法を使用することです。これを使用しているDoCopyFScr()画面の一部をキャプチャしBitmap2ByteArr()、ビットマップをByteArrとして保存し、後で必要に応じてbyte []を使用して保存し、画面上のキャプチャされた場所と比較します。

    public void DoCopyFScr(Point SourceP, Size Mysz, string initDir, string Fname, bool SaveIt, bool DoCompare)
    {

        SetForegroundWindow(A window handle suplied here);
        pause(200);
        Point pZero = new Point(0, 0);

        using (Bitmap bitmap = new Bitmap(Mysz.Width, Mysz.Height))
        {
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                g.CopyFromScreen(SourceP, pZero, Msyz);
            }
            Image img = (Image)bitmap;
            Clipboard.SetImage(img);
            ItsCopiedFromScreen = true;
            MyBtmpToByteArr b2arr = new MyBtmpToByteArr();// inststance of My bitmap to byte[]

            AAdToAppLog("start Converting Bitmap To ByteArr");// logging programs activity in a listview via reflection
            MyCuptredBtmpToolBox.CuptByteArr = b2arr.Bitmap2ByteArr(bitmap);
            AAdToAppLog("Done Convertion ArrSize " + b2arr.Bitmap2ByteArr(bitmap).Length + ", Resting CopyDestionation SelctdIndx");
                                Combo_CopyFromScrn.SelectedIndex = 0;
            if (SaveIt)
            {
                string btmpsRefrenceSave = MyCuptredBtmpToolBox.SourceX_Cuptured.ToString() + "," + MyCuptredBtmpToolBox.SourceY_Cuptured.ToString() + "," + MyCuptredBtmpToolBox.RectWidth_Cuptured.ToString() + "," + MyCuptredBtmpToolBox.RectHeight_Cuptured.ToString() + "," + TBX_FileSaveName.Text;
                if (ItsLoadedFromFile)
                {
                    File.WriteAllBytes(initDir + TBX_FileSaveName.Text, b2arr.Bitmap2ByteArr(bitmap));// See next block Method Bitmap2ByteArr method
                    File.WriteAllText(initDir + TBX_FileSaveName.Text.Replace("bar", "txt"), btmpsRefrenceSave);
                }
                else
                {
                    File.WriteAllBytes(initDir + TBX_FileSaveName.Text + ExtBar, b2arr.Bitmap2ByteArr(bitmap));
                    File.WriteAllText(initDir + TBX_FileSaveName.Text.Replace("bar", "txt") + ExtTXT, btmpsRefrenceSave);
                }
                //MyCuptredBtmpToolBox.CupturedStaticBmp.Save(MyCuptredBtmpToolBox.FnameToSave.Replace(".bar", ".") + ExtJpg, ImageFormat.Jpeg);
                bitmap.Save(initDir + TBX_FileSaveName.Text + ExtJpg, ImageFormat.Jpeg);
            }
            if (DoCompare)
            {
                AAdToAppLog("starting Compare " + Fname +" With Btmp2Arr From Screen");
                R_ComparwByteArrClass tstCmp = new R_ComparwByteArrClass();
                if (itsAutomated)
                {
                    CompareByt2Btmp = R_ComparwByteArrClass.ByteArrCompare(DoAutoLoadCuptByteArr(initDir, Fname + ExtBar), b2arr.Bitmap2ByteArr(bitmap));
                }
                else
                {
                    CompareByt2Btmp = R_ComparwByteArrClass.ByteArrCompare(MyLoadedBtmpToolBox.LoadedByteArr, b2arr.Bitmap2ByteArr(bitmap));
                }
                bring(MyApp);
                AAdToAppLog(CompareByt2Btmp.ToString());

            }
        }

    }

キャプチャされたbtmpをbyte[]に変換するメソッドを使用したビットビットからByteArrクラスへの変換

  public class MyBtmpToByteArr
    {


        public byte[] Bitmap2ByteArr(Bitmap btmpToConvertintoByteArr)
        {


            //Convert image to a byte array
            System.Drawing.ImageConverter MyImgCvrtr = new System.Drawing.ImageConverter();
            byte[] btImage = new byte[1];
            btImage = (byte[])MyImgCvrtr.ConvertTo(btmpToConvertintoByteArr, btImage.GetType());


            return btImage;
        }
    }

しかし、場所が変更された場合、画面上に画像の新しい場所を指定しても識別できません。ただし、テストを行ったときに、ペイントを使用し、グリッドをオンにして、同じトリミングされた画像の2つのコピーを配置しました。成功しましたが、いくつかのアイコンの背景が共有されているゲーム画面の実際のシナリオでは、それらを互いに比較しようとしましたが、場所を指定しても成功しませんでした。ピクセルよりも小さいユニットがありますか?たぶん、ゲームのグラフィックは、ピクセルのほんの一部である一種のユニットを使用していますか?または他のユニットなので、指定された場所Point1は最初のアイコンのX100 Y100であり、200,200ではなく他のユニットは実際には200.33、200.55程度です...そしてそれがデッドロックの位置/場所を取得しない理由ですか?psそうでない場合は、diretxを使用していると思います」ピクセルよりも小さい単位はまったく存在しますか...そして一般的に使用されますか? そうでない場合は、たとえばx100からx150およびy100からy150にループする関数をどのように実装して、画像を検索できるようにしますか

4

2 に答える 2

0

おそらく表示されるのは、スケーリング、エイリアシング、またはサブピクセル ヒンティングとは異なるレンダリング アーティファクトです。

たとえば、WPF ベースのアプリケーションは DPI に依存しないため、ピクセルではなく「表示ポイント」を使用し、見ている動作の種類を説明できる表示ポイントの一部を持つことができます。

「ピクセル」は非常に物理的なもの (モニター上のポイント) ですが、すべてが厳密に現実世界のピクセルに 1:1 でマッピングされているわけではありません。

代わりに、同様の画像を比較するためのより巧妙なメカニズムが必要になります。この関連するスタックオーバーフローの投稿は、開始するのに適した場所かもしれません.

于 2012-08-29T14:47:51.763 に答える
0

私の質問MySelfの2番目の部分を作りました

StpX 、StpY はループの最大反復を制限します

キャプチャの場所である元のポイントはinitPoint CountDown で、最後まで残っているラウンド数を計算しています。内側のループには、検索が成功したときにトリガーされる「ハンド ブレーク」があります。

        Point SearchFromPoint = Point.Empty;
        Point initPoint = new Point(150, 100);
        Size imgSz = new Size(320, 240);
        int StpX = initPoint.X + 1, StpY = initPoint.Y + 1;

        int CountDownX, CountDownY;
        for (int StrtX = initPoint.X - extraX; StrtX < StpX; StrtX++)
        {
            SearchFromPoint.X = StrtX;
            for (int StrtY = initPoint.Y - extraY; StrtY < StpY; StrtY++)
            {
                CountDownX = (initPoint.X - StrtX); CountDownY=(initPoint.Y - StrtY);
                 SearchFromPoint.Y = StrtY;
                AAdToAppLog("Search Report For: " + imgName + " Still trying Search On " + CountDownX + ":" + CountDownY +" Point(" + SearchFromPoint.X + ", " + SearchFromPoint.Y + ")");
                DoCopyFScr(SearchFromPoint, tmpSz, initDir, Fname, false, true);
                    if (CompareByt2Btmp.ToString() == R_ComparwByteArrClass.CompHashResult.HashCompare_Ok.ToString())
                    {
                        same = true;
                        AAdToAppLog("Search Report For: " + imgName + "Search Completed Successfully On Try " + CountDownX + ":" + CountDownY);

                        break;
                    }
            }

        }

これが私が思うことです...固定された既知の場所のシナリオとは対照的に、検索方法を締めくくります。

この件についてコメントしたいことがあれば、自由に投稿してください。

于 2012-08-30T06:38:08.777 に答える