единицы меньше пикселя, поиск частичного изображения экрана в большей части экрана.

все дело в том, что с помощью метода CopyFromScreen() я смог сравнить изображение (захваченное ранее) с изображением, которое совпадает с захваченным, потому что оно фактически захвачено с этого конкретного экрана.

или проще, например, значок, обрезанный с рабочего стола и сохраненный как изображение вместе с текстовым файлом, указывающим его местоположение (точку) и его размер (размер (h, w))

поэтому, когда мы записали .bar через File.WriteAllBytes(byte[]made it .bar) в файл + cuptured.txt со ссылкой на местоположение и размер, у нас есть копия, сохраненная на жестком диске, а также ее местоположение и размер в txt. (мне не нужно было публиковать весь код, но он отлично работает, поэтому, если кому-то это нужно, я делюсь, не стесняйтесь)

способ, которым я достиг этого, заключается в использовании метода, который я сделал DoCopyFScr() - для захвата части экрана, которая использует Bitmap2ByteArr() - сохранение растрового изображения как ByteArr, а затем позже, когда это необходимо, с использованием байта [] - сохранено, чтобы сравнить с его захваченным местоположением на экране.

    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());

            }
        }

    }

растровое изображение в класс ByteArr с методом преобразования захваченного btmp в byte[]

  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;
        }
    }

но если местоположение изменено, я не могу его идентифицировать, даже если я указал новое местоположение изображения на экране, хотя, когда я тестировал, используя краску и с включенной сеткой, я расположил две копии одного и того же обрезанного изображения, и я добился успеха, но в реальном сценарии с игровым экраном, где есть общий фон для нескольких значков, я пытаюсь сравнить их друг с другом и не преуспеваю, хотя я указал местоположение, есть ли единица измерения меньше пикселя может графика в игре использует некую единицу измерения это доли пикселя?? или, может быть, другая единица измерения, поэтому, возможно, заданное местоположение Point1 равно X100 Y100 для первого значка, а другое вместо 200 200 на самом деле находится в 200,33, 200,55 или около того ... и поэтому я не получаю позицию / местоположение мертвой блокировки? ps я думаю, что он использует diretx, если нет, это на openGL, почти наверняка на directx, если это имеет значение для того, какие единицы используются для поиска изображений существует ли единица меньше пикселей вообще ... и широко используется? если нет, как бы вы реализовали функцию, которая будет зацикливаться, скажем, от x100 до x150 и от y100 до y150, чтобы я мог искать изображение


person LoneXcoder    schedule 29.08.2012    source источник
comment
Не думайте, что есть что-то меньше пикселя, который настолько мал, насколько это возможно, но он может быть в какой-то другой единице, такой как «Точка».   -  person Viezevingertjes    schedule 29.08.2012


Ответы (2)


То, что вы, вероятно, видите, отличается артефактами рендеринга от масштабирования, алиасинга или субпиксельного хинтинга.

Например, приложения на основе WPF не зависят от DPI, поэтому они используют «точки отображения» вместо пикселей, и у вас может быть часть точки отображения, которая может учитывать поведение, которое вы видите.

«Пиксель» — это очень физическая вещь (точка на вашем мониторе), но не все строго имеет сопоставление 1: 1 с пикселями реального мира.

Поэтому вместо этого вам понадобится более умный механизм для сравнения похожих изображений — эта связанная запись о стеке о потоке может быть хорошим местом для начала.

person PhonicUK    schedule 29.08.2012

Сделал вторую часть моего Вопроса Себе

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;
                    }
            }

        }

и это то, что я думаю ... заключает метод поиска в отличие от сценария с фиксированным известным местоположением.

если есть что-то, что вы хотите прокомментировать, не стесняйтесь публиковать.

person LoneXcoder    schedule 30.08.2012