c# - 无泄漏中断循环

标签 c# bitmap

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

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

最佳答案

对于不安全的代码,最后用 try 包围它,总是解锁位图并释放您在内部分配的任何内存

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# 的第 3 方图像工具软件库,您有 AForge.NET

关于c# - 无泄漏中断循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38275891/

相关文章:

c# - 帮助 ASP.NET MVC HtmlHelper API 设计

android - 将NV21字节数组转换为位图可读格式

windows - 如何在 BITMAP 被 win32 加载后编辑它

android - 在位图上绘制文本

.net - 如何从 Graphics 对象创建 Bitmap 对象?

c# - 生成带有一些透明部分的图像

c# - 如何在 Windows 和 IANA 时区之间进行转换?

c# - 避免在 Visual Studio 中自动生成命名空间。如何关闭 "using System;"的自动插入

c# - C# 中的共享点编程

java - 缓存谷歌地图v2标记位图