Проверка, чтобы увидеть, если область экрана изменения


Я тестирую некоторые методы проверки, если область изменения экрана, может вы видите какие-либо проблемы с тем, как я делаю это, и есть ли лучший способ для меня сделать это?

в _memoryImage2 не изменится в заключительной приложение, оно будет только для чтения массив, который я буду проверять memoryImage против.

namespace ScreenShot_BoundsTest
{
    public partial class Form1 : Form
    {
        Bitmap _memoryImage1;
        Bitmap _memoryImage2;

        Color[,] _first;
        Color[,] _second;

        private string _valueX;

        public Form1()
        {
            InitializeComponent();
        }

        private void Button1Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }

        private void GetImage()
        {
            _memoryImage2 = _memoryImage1;
            CaptureScreen();
            pictureBox2.Image = pictureBox1.Image;
            if (_memoryImage1 != null) _first = Bitmap2Imagearray(_memoryImage1);

            pictureBox1.Image = _memoryImage1;
            if (_memoryImage2 != null) _second = Bitmap2Imagearray(_memoryImage2);

            var x = CompareArrays();

            _valueX = x != true ? "false" : "true";
        }

        private bool CompareArrays()
        {
            for (var i = 0; i < _memoryImage1.Width; i++)
            {
                for (var j = 0; j < _memoryImage1.Height; j++)
                {
                    if (_first == null) continue;
                    if (_second != null)
                        if (_first[i,j] != _second[i,j])
                        {
                            return false;
                        }
                }
            }
            return _first != null && _second != null;
        }

        private void CaptureScreen()
        {
            Size s;
            using (var myGraphics = CreateGraphics())
            {
                s = new Size(100, 50);
                _memoryImage1 = new Bitmap(s.Width, s.Height, myGraphics);
            }

            var memoryGraphics = Graphics.FromImage(_memoryImage1);
            memoryGraphics.CopyFromScreen(100, 100, 10, 10, s);
        }

        private static Color[,] Bitmap2Imagearray(Bitmap b)
        {
            var imgArray = new Color[b.Width, b.Height];
            for (var y = 0; y < b.Height; y++)
            {
                for (var x = 0; x < b.Width; x++)
                {
                    imgArray[x, y] = b.GetPixel(x, y);
                }
            }
            return imgArray;
        }

        private void BackgroundWorker1DoWork(object sender, DoWorkEventArgs e)
        {
            GetImage();
            Thread.Sleep(100);
        }

        private void BackgroundWorker1RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            label1.Text = _valueX;
            backgroundWorker1.RunWorkerAsync();
        }    
    }
}


1224
4
c#
задан 21 июня 2011 в 10:06 Источник Поделиться
Комментарии
1 ответ

Давайте начнем с алгоритма. Вы используете растровое изображение.Метода getpixel для преобразования всей растровое изображение пиксель за пикселем в матрице цветов. Я попробовал этот подход несколько лет назад - это было довольно медленно .Net 2.0 и я предполагаю, что это еще медленно. Вы должны конвертировать изображения в байт[] и извлечь цвет байт из массива, следует сто раз быстрее. Посмотрите на рисунок.Lockbits прямой метод и метод BitmapData класс.

Остальные пункты о читабельности кода. Существует несколько общих правил, которые могут улучшить читабельность много:


  1. Если метод какого-то результата выполнения затем вернуть этот результат , вместо того, чтобы присвоить его какой-то области. Также использование параметров метод принимает аргументы, а не поля класса.

  2. Если переменная не нужна за пределами одного метода, области тогда не объявить поле для него, использовать локальную переменную вместо.

  3. Быть типизированы. Ничего не приведение к строке, пока вы действительно нуждаетесь в строку.

Эти простые правила применяются к вашему виду код:


  1. Правила #1 и #3 означает, что ваши методы должны иметь следующие подписи:


    • недействительным образец getimage() -> bool и CompareCurrentImageWithPrevious()

    • боол CompareArrays() -> статический боол CompareImageArrays(цвет[,] imageArray1, цвет[,] imageArray2)

    • пустота CaptureScreen() -> растровые CaptureScreen()


  2. Это

    var x = CompareArrays();
    _valueX = x != true ? "false" : "true";

    Следует заменить:

    return CompareArrays(); 

  3. Это

    for (var i = 0; i < _memoryImage1.Width; i++)
    {
    for (var j = 0; j < _memoryImage1.Height; j++)
    {
    if (_first == null) continue;
    if (_second != null)
    if (_first[i,j] != _second[i,j])
    {
    return false;
    }
    }
    }
    return _first != null && _second != null;

    Должно быть:

     if (_first == null || _second == null) return false;
    if (_memoryImage1.Width != _memoryImage2.Width ||
    _memoryImage1.Height != _memoryImage2.Height)
    return false;
    return _first.SequenceEquals(_second);

  4. Не назначайте результате образец getimage() в поле класса, DoWorkEventArgs иметь результатом имущества, которое может использоваться, чтобы возвратить значение, вычисленное на фон рабочего.

    private void BackgroundWorker1DoWork(object sender, DoWorkEventArgs e)
    {
    e.Result = GetImage();
    Thread.Sleep(100);
    }

8
ответ дан 22 июня 2011 в 09:06 Источник Поделиться