Поиск растрового изображения внутри растрового изображения в C # - Не работает на сервере? - PullRequest
0 голосов
/ 21 марта 2019

Я пытаюсь автоматизировать что-то с помощью своего приложения C #, для которого я использую систему обнаружения растровых изображений, чтобы определить, появился ли значок на экране.Это отлично работает на ПК.Однако когда я помещаю приложение на сервер, оно никогда не работает.Я использую экземпляр Google Cloud с Tesla K80, 2 vcpus под управлением Windows Server 2012.

Вот мой код:

    // Capture the current screen as a bitmap
    public static Bitmap CaptureScreen()
    {
        // Bitmap format
        Bitmap ScreenCapture = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);

        // Capture screen
        Graphics GFX = Graphics.FromImage(ScreenCapture);
        GFX.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
            Screen.PrimaryScreen.Bounds.Y, 0, 0,
            ScreenCapture.Size, CopyPixelOperation.SourceCopy);

        return ScreenCapture;
    }

    // Find a list of all the points of a bitmap within another bitmap
    public static List<Point> FindBitmapsEntry(Bitmap SourceBitmap, Bitmap SearchedBitmap)
    {
        #region Arguments check

        if (SourceBitmap == null || SearchedBitmap == null)
            throw new ArgumentNullException();

        if (SourceBitmap.PixelFormat != SearchedBitmap.PixelFormat)
            throw new ArgumentException("Pixel formats aren't equal.");

        if (SourceBitmap.Width < SearchedBitmap.Width || SourceBitmap.Height < SearchedBitmap.Height)
            throw new ArgumentException("Size of SearchedBitmap is bigger than SourceBitmap!");

        #endregion

        var PixelFormatSize = Image.GetPixelFormatSize(SourceBitmap.PixelFormat) / 8;

        // Copy SourceBitmap to byte array
        var SourceBitmapData = SourceBitmap.LockBits(new Rectangle(0, 0, SourceBitmap.Width, SourceBitmap.Height),
            ImageLockMode.ReadOnly, SourceBitmap.PixelFormat);
        var SourceBitmapByteLength = SourceBitmapData.Stride * SourceBitmap.Height;
        var SourceBytes = new byte[SourceBitmapByteLength];

        Marshal.Copy(SourceBitmapData.Scan0, SourceBytes, 0, SourceBitmapByteLength);
        SourceBitmap.UnlockBits(SourceBitmapData);

        // Copy SearchedBitmap to byte array
        var SearchingBitmapData =
            SearchedBitmap.LockBits(new Rectangle(0, 0, SearchedBitmap.Width, SearchedBitmap.Height),
                ImageLockMode.ReadOnly, SearchedBitmap.PixelFormat);
        var SearchingBitmapByteLength = SearchingBitmapData.Stride * SearchedBitmap.Height;
        var SearchingBytes = new byte[SearchingBitmapByteLength];

        Marshal.Copy(SearchingBitmapData.Scan0, SearchingBytes, 0, SearchingBitmapByteLength);
        SearchedBitmap.UnlockBits(SearchingBitmapData);

        var PointsList = new List<Point>();

        // Searching entries, minimizing searching zones
        // SourceBitmap.Height - SearchedBitmap.Height + 1
        for (var MainY = 0; MainY < SourceBitmap.Height - SearchedBitmap.Height + 1; MainY++)
        {
            var SourceY = MainY * SourceBitmapData.Stride;

            for (var MainX = 0; MainX < SourceBitmap.Width - SearchedBitmap.Width + 1; MainX++)
            {
                // MainY & MainX - pixel coordinates of SourceBitmap
                // SourceY + SourceX = pointer in array SourceBitmap bytes
                var SourceX = MainX * PixelFormatSize;

                var IsEqual = true;
                for (var c = 0; c < PixelFormatSize; c++)
                {
                    // Check through the bytes in pixel
                    if (SourceBytes[SourceX + SourceY + c] == SearchingBytes[c])
                        continue;

                    IsEqual = false;
                    break;
                }

                if (!IsEqual) continue;

                var ShouldStop = false;

                // Find first equation and search deeper
                for (var SecY = 0; SecY < SearchedBitmap.Height; SecY++)
                {
                    var SearchY = SecY * SearchingBitmapData.Stride;
                    var SourceSecY = (MainY + SecY) * SourceBitmapData.Stride;

                    for (var SecX = 0; SecX < SearchedBitmap.Width; SecX++)
                    {
                        // SecX & SecY - coordinates of SearchingBitmap
                        // SearchX + SearchY = pointer in array SearchingBitmap bytes
                        var SearchX = SecX * PixelFormatSize;
                        var SourceSecX = (MainX + SecX) * PixelFormatSize;

                        for (var c = 0; c < PixelFormatSize; c++)
                        {
                            // Check through the bytes in pixel
                            if (SourceBytes[SourceSecX + SourceSecY + c] == SearchingBytes[SearchX + SearchY + c]) continue;

                            // Not equal - abort iteration
                            ShouldStop = true;
                            break;
                        }

                        if (ShouldStop) break;
                    }

                    if (ShouldStop) break;
                }

                if (!ShouldStop) // Bitmap is found
                {
                    PointsList.Add(new Point(MainX, MainY));
                }
            }
        }

        return PointsList;
    }

И вот как я его использую:

            Bitmap HighlightBitmap = new Bitmap(Resources.icon);
            Bitmap CurrentScreen = CaptureScreen();

            List<Point> HighlightPoints = FindBitmapsEntry(CurrentScreen, HighlightBitmap);

с этими HighlightPoints [0] должен дать мне первую точку, когда две битовые карты (значок, скриншот) сталкиваются.Но, как упоминалось ранее, он просто не работает на сервере.

Заранее спасибо!

PS Я использую сервер с RDP, поэтому он имеет визуальный интерфейс для работы с

...