中断循环无泄漏

本文关键字:泄漏 循环 中断 | 更新日期: 2023-09-27 17:56:09

我有简单的代码试图在屏幕上找到像素序列。

    两个
  1. 如何在函数FindPixelSequence中打破两个循环而不会发生内存泄漏什么时候发生if (isEqual)
  2. 如何改进现有代码?

namespace FindColor
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        PlayWithColor PWC = new PlayWithColor();
        List<System.Drawing.Color> pixels { get; set; }
        public MainWindow()
        {
            InitializeComponent();
            pixels = new List<System.Drawing.Color>();
            pixels.Add(System.Drawing.Color.FromArgb(0, 0, 0, 0));
            pixels.Add(System.Drawing.Color.FromArgb(0, 153, 255, 0));
            pixels.Add(System.Drawing.Color.FromArgb(0, 153, 255, 0));
            pixels.Add(System.Drawing.Color.FromArgb(0, 128, 214, 0));
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            using (var bitmap = PWC.TakeScreen())
            {
                PWC.FindPixelSequence(bitmap, pixels);
            }
        }
    }
    class ColorEqualityComparer : IEqualityComparer<Color>
    {
        public bool Equals(Color b1, Color b2)
        {
            return b1.R == b2.R && b1.G == b2.G && b1.B == b2.B;
        }
        public int GetHashCode(Color obj)
        {
            throw new NotImplementedException();
        }
    }
    public class PlayWithColor
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern bool SetCursorPos(int x, int y);
        private Bitmap bmpScreenshot { get; set; }
        public Bitmap TakeScreen()
        {
            bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                               Screen.PrimaryScreen.Bounds.Height,
                               PixelFormat.Format32bppArgb);
            var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
            int sourceX = Screen.PrimaryScreen.Bounds.X;
            int sourceY = Screen.PrimaryScreen.Bounds.Y;
            gfxScreenshot.CopyFromScreen(sourceX,
                                        sourceY,
                                        0,
                                        0,
                                        Screen.PrimaryScreen.Bounds.Size,
                                        CopyPixelOperation.SourceCopy);
            return bmpScreenshot;
        }
        public System.Drawing.Point? FindPixelSequence(Bitmap bitmap, List<Color> pixels)
        {
            Stopwatch watch = new Stopwatch();
            List<Color> currentPixels;
            watch.Start();
            BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
               ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            unsafe
            {
                byte* ptrSrc = (byte*)data.Scan0;
                for (int y = 0; y < data.Height; y = y + 1)
                {
                    for (int x = 0; x < data.Width; x = x + 1)
                    {
                        currentPixels = new List<Color>();
                        for (int i = 0; i < pixels.Count; i++)
                        {
                            byte r0 = ptrSrc[2];
                            byte g0 = ptrSrc[1];
                            byte b0 = ptrSrc[0];
                            Color currentPixel = Color.FromArgb(0, r0, g0, b0);
                            ptrSrc += 4;
                            currentPixels.Add(currentPixel);
                        }
                        ptrSrc -= (4 * (pixels.Count - 1));
                        bool isEqual = currentPixels.SequenceEqual(pixels, new ColorEqualityComparer());
                        if (isEqual)
                        {
                            SetCursorPos(x, y);
                            //how return coords of x and y from there?
                        }
                    }
                }
            }
            bitmap.UnlockBits(data);
            watch.Stop();
            Debug.WriteLine(watch.ElapsedMilliseconds);
        }
    }
}

中断循环无泄漏

对于不安全的代码,最后尝试一下,始终解锁位图并释放内部分配的任何内存

1.

unsafe
{
    Stopwatch watch = new Stopwatch();
    watch.Start();
    try
    {
         ....
         return new Point(x,y); // To return x,y corrdinates
    }
    finally
    {
        bitmap.UnlockBits(data);
        watch.Stop();
    }
}
  1. 对于简单的代码,我将使用您 AForge.NET 的 C# 的第三方图像工具软件库