断裂循环没有泄漏

时间:2016-07-08 21:53:56

标签: c# bitmap

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

  1. 如何在函数FindPixelSequence中打破两个没有内存泄漏的循环 当if (isEqual)发生时?
  2. 如何改进现有代码?
  3. 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 个答案:

答案 0 :(得分:1)

对于不安全的代码,最后尝试一下,总是解锁位图并释放你在内部分配的内存

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. 只是代码我将使用第三方图像工具软件库为c#你AForge.NET