Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
63 views
in Technique[技术] by (71.8m points)

c# - Find bitmap on another bitmap and the position

Hello im begginer on C# and i have a bitmap with a image wich is updating every X seconds and i have another bitmap with a a model saved(As bitmap too), and i need to find on the main bitmap and get the [X, Y] on my screen where this bitmap is found on my main bitmap, im using a Windows Forms C#, i already searched about it, and i try this code, the first answer but i no understand nothing about this code i dont know how to use, i need a method with return of [X, Y] where is found this bitmap on my screen, here is a example what i need, that is what im trying and on my console even with the btm to found shows nothing.

    private void Form1_Load(object sender, EventArgs e)
    {
        SearchBtm = new Bitmap(@"C:UsersghostDesktopTESTSearchBtm.png");
    }
    
    public void Reader_Tick(object sender, EventArgs e)
    { 
            CurrentBtm = CaptureScreen();
            var d = Find(CurrentBtm, SearchBtm);

            Console.WriteLine(d);
    }

    public Point? Find(Bitmap haystack, Bitmap needle)
    {
        if (null == haystack || null == needle)
        {
            return null;
        }
        if (haystack.Width < needle.Width || haystack.Height < needle.Height)
        {
            return null;
        }

        var haystackArray = GetPixelArray(haystack);
        var needleArray = GetPixelArray(needle);

        foreach (var firstLineMatchPoint in FindMatch(haystackArray.Take(haystack.Height - needle.Height), needleArray[0]))
        {
            if (IsNeedlePresentAtLocation(haystackArray, needleArray, firstLineMatchPoint, 1))
            {
                return firstLineMatchPoint;
            }
        }

        return null;
    }

    private int[][] GetPixelArray(Bitmap bitmap)
    {
        var result = new int[bitmap.Height][];
        var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly,
            PixelFormat.Format32bppArgb);

        for (int y = 0; y < bitmap.Height; ++y)
        {
            result[y] = new int[bitmap.Width];
            Marshal.Copy(bitmapData.Scan0 + y * bitmapData.Stride, result[y], 0, result[y].Length);
        }

        bitmap.UnlockBits(bitmapData);

        return result;
    }

    private IEnumerable<Point> FindMatch(IEnumerable<int[]> haystackLines, int[] needleLine)
    {
        var y = 0;
        foreach (var haystackLine in haystackLines)
        {
            for (int x = 0, n = haystackLine.Length - needleLine.Length; x < n; ++x)
            {
                if (ContainSameElements(haystackLine, x, needleLine, 0, needleLine.Length))
                {
                    yield return new Point(x, y);
                }
            }
            y += 1;
        }
    }

    private bool ContainSameElements(int[] first, int firstStart, int[] second, int secondStart, int length)
    {
        for (int i = 0; i < length; ++i)
        {
            if (first[i + firstStart] != second[i + secondStart])
            {
                return false;
            }
        }
        return true;
    }

    private bool IsNeedlePresentAtLocation(int[][] haystack, int[][] needle, Point point, int alreadyVerified)
    {
        //we already know that "alreadyVerified" lines already match, so skip them
        for (int y = alreadyVerified; y < needle.Length; ++y)
        {
            if (!ContainSameElements(haystack[y + point.Y], point.X, needle[y], 0, needle.Length))
            {
                return false;
            }
        }
        return true;
    }

    public Bitmap CaptureScreen()
    {
        //Getting ScreenBounds
        var ScreenBounds = Screen.FromHandle(this.Handle).Bounds;

        // Creating a new Bitmap
        Bitmap CaptureBitmap = new Bitmap(ScreenBounds.Width, ScreenBounds.Height, PixelFormat.Format32bppArgb);

        // Capture Rectangle
        Rectangle CaptureRectangle = ScreenBounds;

        // Graphics Object
        Graphics CaptureGraphics = Graphics.FromImage(CaptureBitmap);

        // Copying Image from The Screen
        CaptureGraphics.CopyFromScreen(CaptureRectangle.Left, CaptureRectangle.Top, 0, 0, CaptureRectangle.Size);

        // Return
        return CaptureBitmap;
    }
question from:https://stackoverflow.com/questions/65912101/find-bitmap-on-another-bitmap-and-the-position

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...