Exemple #1
0
        /// <summary>
        /// Screen capture to file
        /// </summary>
        /// <param name="screen">The screen want to capture</param>
        /// <param name="filePath">Save image file path</param>
        /// <param name="imageFormat">Image format</param>
        /// <param name="bounds">bounds</param>
        /// <param name="timeOut">timeOut</param>
        /// <param name="cancellationToken">cancellationToken</param>
        /// <returns></returns>
        public async Task ScreenCaptureToFile(Screen screen, string filePath, ImageFormat imageFormat = null,
                                              Rectangle?bounds = null, TimeSpan?timeOut = null,
                                              CancellationToken cancellationToken = default)
        {
            if (WindowsApi.Delay.HasValue)
            {
                await Task.Delay(WindowsApi.Delay.Value, cancellationToken);
            }

            var linkedToken =
                timeOut == null
                    ? cancellationToken
                    : CancellationTokenSource
                .CreateLinkedTokenSource(cancellationToken, new CancellationTokenSource(timeOut.Value).Token)
                .Token;

            using (var screenPixel = await InnerScreenCapture(GetValidIntersectRectangle(screen, bounds), linkedToken))
            {
                if (screenPixel != null)
                {
                    linkedToken.ThrowIfCancellationRequested();
                    if (imageFormat != null)
                    {
                        screenPixel.Save(filePath, imageFormat);
                        WindowsApi.WriteLog(
                            $"{nameof(ScreenCaptureToFile)} Save to {filePath} with {nameof(imageFormat)}:{imageFormat}");
                    }
                    else
                    {
                        screenPixel.Save(filePath);
                        WindowsApi.WriteLog($"{nameof(ScreenCaptureToFile)} Save to {filePath}");
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Get color at point.
        /// </summary>
        /// <param name="point">point</param>
        /// <returns>color</returns>
        public Color GetColorAt(Point point)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            var screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb);

            using (var dest = Graphics.FromImage(screenPixel))
            {
                using (var src = Graphics.FromHwnd(IntPtr.Zero))
                {
                    var hSrcDc = src.GetHdc();
                    var hDc    = dest.GetHdc();
                    BitBlt(hDc, 0, 0, 1, 1, hSrcDc, point.X, point.Y, (int)CopyPixelOperation.SourceCopy);
                    dest.ReleaseHdc();
                    src.ReleaseHdc();
                }
            }

            var color = screenPixel.GetPixel(0, 0);

            WindowsApi.WriteLog(
                $"{nameof(GetColorAt)} {nameof(point.X)}:{point.X},{nameof(point.Y)}:{point.Y} {nameof(color)}:{color}");

            return(color);
        }
Exemple #3
0
 internal HotKeyHelper()
 {
     HotkeyManager.HotkeyAlreadyRegistered += (sender, args) =>
     {
         WindowsApi.WriteLog($"Hot key {args.Name} already register");
         HotkeyAlreadyRegistered?.Invoke(sender, args);
     };
 }
Exemple #4
0
        /// <summary>
        /// Get color at point.
        /// </summary>
        /// <param name="point">point</param>
        /// <param name="wantColor">want color</param>
        /// <param name="timeOut">timeOut</param>
        /// <param name="cancellationToken">cancellationToken</param>
        /// <returns>If wait unit time out, the return color is null.</returns>
        public async Task <bool> WaitColorNotAt(Point point, Color wantColor, TimeSpan?timeOut = null,
                                                CancellationToken cancellationToken            = default)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            Color?color;

            var linkedToken =
                timeOut == null
                    ? cancellationToken
                    : CancellationTokenSource
                .CreateLinkedTokenSource(cancellationToken, new CancellationTokenSource(timeOut.Value).Token)
                .Token;

            var getColor = false;

            await Task.Run(async() =>
            {
                using (var screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
                {
                    do
                    {
                        linkedToken.ThrowIfCancellationRequested();

                        using (var dest = Graphics.FromImage(screenPixel))
                        {
                            using (var src = Graphics.FromHwnd(IntPtr.Zero))
                            {
                                var hSrcDc = src.GetHdc();
                                var hDc    = dest.GetHdc();
                                BitBlt(hDc, 0, 0, 1, 1, hSrcDc, point.X, point.Y, (int)CopyPixelOperation.SourceCopy);
                                dest.ReleaseHdc();
                                src.ReleaseHdc();
                            }
                        }

                        color = screenPixel.GetPixel(0, 0);

                        await Task.Delay(5, linkedToken);
                        WindowsApi.WriteLog(
                            $"{nameof(GetColorAt)} {nameof(point.X)}:{point.X},{nameof(point.Y)}:{point.Y} {nameof(color)}:{color.Value}");

                        if (color != wantColor)
                        {
                            getColor = true;
                            WindowsApi.WriteLog(
                                $"{nameof(WaitColorAt)} {nameof(point.X)}:{point.X},{nameof(point.Y)}:{point.Y} {nameof(color)} isn't {color.Value}");
                        }
                    } while (!getColor);
                }
            }, linkedToken);

            return(getColor);
        }
Exemple #5
0
        /// <summary>
        /// 鼠标抬起
        /// </summary>
        /// <param name="rightButton">右键</param>
        public void MouseButtonUp(bool rightButton = false)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            mouse_event(rightButton ? MouseEventFlag.RightUp : MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);
            WindowsApi.WriteLog($"{nameof(MouseButtonUp)} {GetButtonString(rightButton)}");
        }
Exemple #6
0
        /// <summary>
        /// KeyBoard down
        /// </summary>
        /// <param name="key">key name</param>
        public void KeyDown(Key key)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            keybd_event((byte)KeyInterop.VirtualKeyFromKey(key), 0, KeyDownFlag, IntPtr.Zero);
            WindowsApi.WriteLog($"{nameof(KeyDown)} {key}");
        }
Exemple #7
0
        /*
         * /// <summary>
         * /// 鼠标按压
         * /// </summary>
         * /// <param name="offsetX">offsetX</param>
         * /// <param name="offsetY">offsetY</param>
         * /// <param name="rightButton">右键</param>
         * /// <param name="pressedMillionSeconds">按压时长</param>
         * /// <param name="cancellationToken">cancellationToken</param>
         * [Obsolete("It's imprecise.", true)]
         * public async Task MousePressed(int offsetX, int offsetY, bool rightButton = false, uint pressedMillionSeconds = MousePressedTime, CancellationToken cancellationToken = default)
         * {
         *  MouseMove(offsetX, offsetY);
         *  await MousePressed(rightButton, pressedMillionSeconds, cancellationToken);
         * }
         */

        /// <summary>
        /// 鼠标滚轮
        /// </summary>
        /// <param name="wheelDelta">正值表明鼠标轮向前转动,即远离用户的方向;负值表明鼠标轮向后转动,即朝向用户。</param>
        public void MouseWheel(int wheelDelta = 500)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            mouse_event(MouseEventFlag.Wheel, 0, 0, wheelDelta, UIntPtr.Zero);
            WindowsApi.WriteLog($"{nameof(MouseWheel)} {nameof(wheelDelta)}:{wheelDelta}");
        }
Exemple #8
0
        /// <summary>
        /// Activate the form using the form handle.
        /// </summary>
        /// <param name="hWnd">form handle</param>
        public void SwitchToThisWindow(IntPtr hWnd)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            //激活显示在最前面
            SwitchToThisWindow(hWnd, true);
            WindowsApi.WriteLog($"{nameof(SwitchToThisWindow)} handle is {hWnd}.");
        }
Exemple #9
0
        /*
         * /// <summary>
         * /// 鼠标移动到相对当前鼠标的位置
         * /// </summary>
         * /// <param name="offsetX">offsetX</param>
         * /// <param name="offsetY">offsetY</param>
         * [Obsolete("It's imprecise.", true)]
         * public void MouseMove(int offsetX, int offsetY)
         * {
         *  if (WindowsApi.Delay.HasValue)
         *  {
         *      Thread.Sleep(WindowsApi.Delay.Value);
         *  }
         *
         *  mouse_event(MouseEventFlag.Move, offsetX, offsetY, 0, UIntPtr.Zero);
         *  WindowsApi.WriteLog($"{nameof(MouseMove)} {nameof(offsetX)}:{offsetX},{nameof(offsetY)}:{offsetY}");
         * }
         */

        /// <summary>
        /// 鼠标移动到绝对位置
        /// </summary>
        /// <param name="point">鼠标要移动到的绝对位置</param>
        /// <param name="delayPerPixel">每像素停留时间</param>
        /// <param name="cancellationToken">cancellationToken</param>
        /// <returns></returns>
        public async Task MouseMove(MousePoint point, uint delayPerPixel, CancellationToken cancellationToken = default)
        {
            if (WindowsApi.Delay.HasValue)
            {
                await Task.Delay(WindowsApi.Delay.Value, cancellationToken);
            }

            await Task.Run(async() =>
            {
                var currentPoint = GetCurrentMousePoint();
                var currentX     = currentPoint.X;
                var currentY     = currentPoint.Y;

                var delayTimeSpan = TimeSpan.FromMilliseconds(delayPerPixel);

                while (currentPoint != point)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (currentX < point.X)
                    {
                        currentX++;
                    }
                    else if (currentX > point.X)
                    {
                        currentX--;
                    }

                    if (currentY < point.Y)
                    {
                        currentY++;
                    }
                    else if (currentY > point.Y)
                    {
                        currentY--;
                    }

                    currentPoint = new MousePoint(currentX, currentY);
                    var bounds   = _innerScreenApi.Value.GetMouseScreen(currentPoint).Bounds;
                    mouse_event(MouseEventFlag.Absolute | MouseEventFlag.Move, currentPoint.X * (MagicNumber / bounds.Width),
                                currentPoint.Y * (MagicNumber / bounds.Height),
                                0, UIntPtr.Zero);

                    if (delayPerPixel > 0u)
                    {
                        await Task.Delay(delayTimeSpan, cancellationToken);
                    }
                }

                WindowsApi.WriteLog(
                    $"{nameof(MouseMove)} from {nameof(MousePoint.X)}:{currentPoint.X},{nameof(MousePoint.Y)}:{currentPoint.Y} to {nameof(MousePoint.X)}:{point.X},{nameof(MousePoint.Y)}:{point.Y}");
            }, cancellationToken);
        }
Exemple #10
0
        /// <summary>
        /// KeyBoard up
        /// </summary>
        /// <param name="keys">key names</param>
        public void KeyUp(params Key[] keys)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            foreach (var key in keys)
            {
                keybd_event((byte)KeyInterop.VirtualKeyFromKey(key), 0, KeyUpFlag, IntPtr.Zero);
                WindowsApi.WriteLog($"{nameof(KeyUp)} {key}");
            }
        }
Exemple #11
0
        /// <summary>
        /// Precision match
        /// </summary>
        /// <param name="wantBitmap">Want match bitmap</param>
        /// <param name="bitmap">target bitmap</param>
        /// <param name="cancellationToken">cancellationToken</param>
        /// <returns>Target bitmap location</returns>
        private async Task <Rectangle?> PrecisionMatchLocation(Bitmap wantBitmap, Bitmap bitmap,
                                                               CancellationToken cancellationToken)
        {
            return(await Task.Run(() =>
            {
                var index = 0;

                for (var x = 0; x <= bitmap.Size.Width - wantBitmap.Width; x++)
                {
                    for (var y = 0; y <= bitmap.Size.Height - wantBitmap.Height; y++)
                    {
                        var isMatch = true;

                        for (var x2 = 0; x2 < wantBitmap.Size.Width; x2++)
                        {
                            for (var y2 = 0; y2 < wantBitmap.Size.Height; y2++)
                            {
                                //降低检查频率
                                if (index++ % 10 == 0)
                                {
                                    cancellationToken.ThrowIfCancellationRequested();
                                }

                                if (bitmap.GetPixel(x + x2, y + y2) != wantBitmap.GetPixel(x2, y2))
                                {
                                    isMatch = false;
                                    break;
                                }

                                if (x2 == wantBitmap.Size.Width - 1 && y2 == wantBitmap.Size.Height - 1)
                                {
                                    var rectangle =
                                        new Rectangle?(new Rectangle(x, y, wantBitmap.Width, wantBitmap.Height));

                                    WindowsApi.WriteLog($"{nameof(PrecisionMatchLocation)} match success, {rectangle}");
                                    return rectangle;
                                }
                            }

                            if (!isMatch)
                            {
                                break;
                            }
                        }
                    }
                }

                WindowsApi.WriteLog($"{nameof(PrecisionMatchLocation)} match failed");
                return null;
            }, cancellationToken));
        }
Exemple #12
0
        /// <summary>
        /// 鼠标移动到绝对位置
        /// </summary>
        /// <param name="point">需要移动到的坐标</param>
        public void MouseMove(MousePoint point)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            var bounds = _innerScreenApi.Value.GetMouseScreen(point).Bounds;

            mouse_event(MouseEventFlag.Absolute | MouseEventFlag.Move, point.X * (MagicNumber / bounds.Width),
                        point.Y * (MagicNumber / bounds.Height),
                        0, UIntPtr.Zero);
            WindowsApi.WriteLog($"{nameof(MouseMove)} {nameof(MousePoint.X)}:{point.X},{nameof(MousePoint.Y)}:{point.Y}");
        }
Exemple #13
0
        /*
         * /// <summary>
         * /// 鼠标双击
         * /// </summary>
         * /// <param name="offsetX">offsetX</param>
         * /// <param name="offsetY">offsetY</param>
         * /// <param name="rightButton">右键</param>
         * [Obsolete("It's imprecise.", true)]
         * public void MouseDoubleClick(int offsetX, int offsetY, bool rightButton = false)
         * {
         *  MouseMove(offsetX, offsetY);
         *  MouseDoubleClick(rightButton);
         * }
         */

        /// <summary>
        /// 鼠标按压
        /// </summary>
        /// <param name="rightButton">右键</param>
        /// <param name="pressedMillionSeconds">按压时长</param>
        /// <param name="cancellationToken">cancellationToken</param>
        public async Task MousePressed(bool rightButton = false, uint pressedMillionSeconds = MousePressedTime, CancellationToken cancellationToken = default)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            await Task.Run(async() =>
            {
                mouse_event(rightButton ? MouseEventFlag.RightDown : MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
                await Task.Delay(TimeSpan.FromMilliseconds(pressedMillionSeconds), cancellationToken);
                mouse_event(rightButton ? MouseEventFlag.RightUp : MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);

                WindowsApi.WriteLog(
                    $"{nameof(MousePressed)} {GetButtonString(rightButton)} {nameof(MousePressedTime)}:{pressedMillionSeconds}");
            }, cancellationToken);
        }
Exemple #14
0
        /// <summary>
        /// Template match
        /// </summary>
        /// <param name="wantBitmap">Want match bitmap</param>
        /// <param name="bitmap">target bitmap</param>
        /// <param name="templateMatch">template match option</param>
        /// <param name="cancellationToken">cancellationToken</param>
        /// <returns>Target bitmap location</returns>
        private async Task <Rectangle?> TemplateMatchLocation(Bitmap wantBitmap, Bitmap bitmap,
                                                              TemplateMatch templateMatch, CancellationToken cancellationToken)
        {
            return(await Task.Run(() =>
            {
                try
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    using var srcMat = bitmap.ToMat();
                    using var dstMat = wantBitmap.ToMat();
                    using var outArray = OutputArray.Create(srcMat);

                    cancellationToken.ThrowIfCancellationRequested();

                    Cv2.MatchTemplate(srcMat, dstMat, outArray, templateMatch.TemplateMatchModel);

                    cancellationToken.ThrowIfCancellationRequested();

                    Cv2.MinMaxLoc(InputArray.Create(outArray.GetMat() !), out _,
                                  out var maxValue, out _, out var point);

                    if (maxValue >= templateMatch.Threshold && maxValue <= 1d)
                    {
                        var rectangle =
                            new Rectangle?(new Rectangle(point.X, point.Y, wantBitmap.Width, wantBitmap.Height));
                        WindowsApi.WriteLog(
                            $"{nameof(TemplateMatchLocation)} match success, {nameof(TemplateMatch.TemplateMatchModel)}:{templateMatch.TemplateMatchModel}, {nameof(TemplateMatch.Threshold)}:{templateMatch.Threshold}, {nameof(maxValue)}:{maxValue}, {rectangle}");

                        return rectangle;
                    }
                    else
                    {
                        WindowsApi.WriteLog(
                            $"{nameof(TemplateMatchLocation)} match failed, {nameof(TemplateMatch.TemplateMatchModel)}:{templateMatch.TemplateMatchModel}, {nameof(TemplateMatch.Threshold)}:{templateMatch.Threshold}, {nameof(maxValue)}:{maxValue}");
                    }
                }
                catch (Exception ex)
                {
                    WindowsApi.WriteLog(
                        $"{nameof(TemplateMatchLocation)} {nameof(TemplateMatch.TemplateMatchModel)}:{templateMatch.TemplateMatchModel}, {nameof(TemplateMatch.Threshold)}:{templateMatch.Threshold}, ErrorMessage:{ex.Message}");
                }

                return null;
            }, cancellationToken));
        }
Exemple #15
0
        /// <summary>
        /// Input text
        /// </summary>
        /// <param name="text">text</param>
        public void InputString(string text)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            if (text != null)
            {
                SendKeys.SendWait(text);
                WindowsApi.WriteLog($"{nameof(InputString)} {nameof(text)} is \"{text}\".");
            }
            else
            {
                WindowsApi.WriteLog($"{nameof(InputString)} {nameof(text)} is null.");
            }
        }
Exemple #16
0
        /// <summary>
        /// 获取当前的鼠标坐标
        /// </summary>
        /// <returns></returns>
        public MousePoint GetCurrentMousePoint()
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            if (GetCursorPos(out var p))
            {
                WindowsApi.WriteLog($"{nameof(GetCurrentMousePoint)} {nameof(MousePoint.X)}:{p.X},{nameof(MousePoint.Y)}:{p.Y}");
                return(p);
            }
            else
            {
                WindowsApi.WriteLog($"{nameof(GetCurrentMousePoint)} operating failed.");
                return(new MousePoint());
            }
        }
Exemple #17
0
        /*
         *
         * /// <summary>
         * /// Activate the process if it not minimize.
         * /// </summary>
         * /// <param name="process">process</param>
         * /// <returns>success</returns>
         * public bool SetForegroundWindow(Process process)
         * {
         *  var result = false;
         *
         *  if (WindowsApi.Delay.HasValue)
         *  {
         *      Thread.Sleep(WindowsApi.Delay.Value);
         *  }
         *
         *  if (process != null)
         *  {
         *      result = SetForegroundWindow(process.MainWindowHandle);
         *      WindowsApi.WriteLog(
         *          $"{nameof(SetForegroundWindow)} {nameof(process)} name is {process.ProcessName}, main window handle is {process.MainWindowHandle}, {nameof(result)} is {result}.");
         *  }
         *  else
         *  {
         *      WindowsApi.WriteLog($"{nameof(SetForegroundWindow)} {nameof(process)} is null.");
         *  }
         *
         *  return result;
         * }
         *
         * /// <summary>
         * /// Activate the form using the form handle if it not minimize.
         * /// </summary>
         * /// <param name="hWnd">form handle</param>
         * /// <returns>success</returns>
         * public bool SetForegroundWindowWithHandle(IntPtr hWnd)
         * {
         *  if (WindowsApi.Delay.HasValue)
         *  {
         *      Thread.Sleep(WindowsApi.Delay.Value);
         *  }
         *
         *  var result = SetForegroundWindow(hWnd);
         *  WindowsApi.WriteLog($"{nameof(SetForegroundWindow)} handle is {hWnd}, {nameof(result)} is {result}.");
         *
         *  return result;
         * }
         *
         */

        #endregion

        /// <summary>
        /// Activate the process.
        /// </summary>
        /// <param name="process"></param>
        public void SwitchToThisWindow(Process process)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            if (process != null)
            {
                SwitchToThisWindow(process.MainWindowHandle, true);
                WindowsApi.WriteLog(
                    $"{nameof(SwitchToThisWindow)} {nameof(process)} name is {process.ProcessName}, main window handle is {process.MainWindowHandle}.");
            }
            else
            {
                WindowsApi.WriteLog($"{nameof(SwitchToThisWindow)} {nameof(process)} is null.");
            }
        }
Exemple #18
0
        /// <summary>
        /// KeyPress
        /// </summary>
        /// <param name="key">key name</param>
        /// <param name="pressedMillionSeconds">pressed time</param>
        /// <returns></returns>
        public static async Task KeyPress(Key key, uint pressedMillionSeconds = KeyPressedTime)
        {
            if (WindowsApi.Delay.HasValue)
            {
                Thread.Sleep(WindowsApi.Delay.Value);
            }

            var keyByte = (byte)KeyInterop.VirtualKeyFromKey(key);

            keybd_event(keyByte, 0, KeyDownFlag, IntPtr.Zero);

            if (pressedMillionSeconds != 0u)
            {
                await Task.Delay(TimeSpan.FromMilliseconds(pressedMillionSeconds));
            }

            keybd_event(keyByte, 0, KeyUpFlag, IntPtr.Zero);
            WindowsApi.WriteLog($"{nameof(KeyPress)} {key} {nameof(KeyPressedTime)}:{pressedMillionSeconds}");
        }
Exemple #19
0
        /// <summary>
        /// Screen capture to stream
        /// </summary>
        /// <param name="screen">The screen want to capture</param>
        /// <param name="imageFormat">Save image file path</param>
        /// <param name="bounds">bounds</param>
        /// <param name="timeOut">timeOut</param>
        /// <param name="cancellationToken">cancellationToken</param>
        /// <returns></returns>
        public async Task <Stream> ScreenCaptureToStream(Screen screen, ImageFormat imageFormat = null,
                                                         Rectangle?bounds = null,
                                                         TimeSpan?timeOut = null,
                                                         CancellationToken cancellationToken = default)
        {
            if (WindowsApi.Delay.HasValue)
            {
                await Task.Delay(WindowsApi.Delay.Value, cancellationToken);
            }

            var linkedToken =
                timeOut == null
                    ? cancellationToken
                    : CancellationTokenSource
                .CreateLinkedTokenSource(cancellationToken, new CancellationTokenSource(timeOut.Value).Token)
                .Token;

            using (var screenPixel = await InnerScreenCapture(GetValidIntersectRectangle(screen, bounds), linkedToken))
            {
                if (screenPixel != null)
                {
                    linkedToken.ThrowIfCancellationRequested();
                    var stream = new MemoryStream();

                    if (imageFormat != null)
                    {
                        screenPixel.Save(stream, imageFormat);
                        WindowsApi.WriteLog(
                            $"{nameof(ScreenCaptureToStream)} save to stream with {nameof(imageFormat)}:{imageFormat}");
                    }
                    else
                    {
                        screenPixel.Save(stream, ImageFormat.Bmp);
                        WindowsApi.WriteLog(
                            $"{nameof(ScreenCaptureToStream)} save to stream with {nameof(imageFormat)}:{ImageFormat.MemoryBmp}");
                    }

                    return(stream);
                }
            }

            return(null);
        }
Exemple #20
0
        /// <summary>
        /// 注册或替换快捷键
        /// </summary>
        /// <param name="identity"></param>
        /// <param name="key"></param>
        /// <param name="modifierKeys"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public bool RegisterOrReplace(string identity, Key key, ModifierKeys modifierKeys, Action action)
        {
            lock (_lock)
            {
                try
                {
                    Remove(identity);

                    var hotKeyIdentity = new HotKeyIdentity(key, modifierKeys);

                    if (_hotKeyCache.ContainsKey(hotKeyIdentity))
                    {
                        _hotKeyCache[hotKeyIdentity].LinkedEventHandler(action, identity);
                    }
                    else
                    {
                        var hotKeyModel = new HotKeyModel(hotKeyIdentity);
                        hotKeyModel.RemoveAllLinkedEvent += HotKeyModelOnRemoveAllLinkedEvent;
                        hotKeyModel.LinkedEventHandler(action, identity);

                        _hotKeyCache.Add(hotKeyIdentity, hotKeyModel);
                    }

                    if (!string.IsNullOrEmpty(identity))
                    {
                        _identityCache.Add(identity, hotKeyIdentity);
                    }

                    return(true);
                }
                catch (HotkeyAlreadyRegisteredException hotkeyAlreadyRegisteredException)
                {
                    WindowsApi.WriteLog($"Hot key {hotkeyAlreadyRegisteredException.Name} already register");
                    HotkeyAlreadyRegistered?.Invoke(HotkeyManager.Current,
                                                    new HotkeyAlreadyRegisteredEventArgs(hotkeyAlreadyRegisteredException.Name));
                }
            }

            return(false);
        }
Exemple #21
0
            /// <summary>
            /// 处理事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="args"></param>
            private void OnHotkeyEventHandler(object sender, HotkeyEventArgs args)
            {
                if (_linkedEventHandlers != null)
                {
                    lock (_linkedEventHandlers)
                    {
                        if (_linkedEventHandlers.RemoveAll(s => !s.IsAlive()) > 0 &&
                            _linkedEventHandlersWithIdentity != null)
                        {
                            var removeIdentity = new List <string>();

                            foreach (var keyValuePair in _linkedEventHandlersWithIdentity)
                            {
                                if (!keyValuePair.Value.IsAlive())
                                {
                                    removeIdentity.Add(keyValuePair.Key);
                                }
                            }

                            foreach (var identity in removeIdentity)
                            {
                                _linkedEventHandlersWithIdentity.Remove(identity);
                            }
                        }

                        foreach (var linkedEventHandler in _linkedEventHandlers)
                        {
                            try
                            {
                                linkedEventHandler.Trigger();
                            }
                            catch (Exception e)
                            {
                                WindowsApi.WriteLog(e.Message);
                                Debug.WriteLine(e);
                            }
                        }
                    }
                }
            }
Exemple #22
0
        /// <summary>
        /// Inner screen capture
        /// </summary>
        /// <param name="realRectangle">The real rectangle</param>
        /// <param name="cancellationToken">cancellationToken</param>
        /// <returns>not null</returns>
        private async Task <Bitmap> InnerScreenCapture(Rectangle realRectangle,
                                                       CancellationToken cancellationToken = default)
        {
            if (realRectangle.Width > 0 && realRectangle.Height > 0)
            {
                return(await Task.Run(() =>
                {
                    var screenPixel = new Bitmap(realRectangle.Width, realRectangle.Height,
                                                 PixelFormat.Format32bppArgb);
                    cancellationToken.ThrowIfCancellationRequested();

                    using (var dest = Graphics.FromImage(screenPixel))
                    {
                        using (var src = Graphics.FromHwnd(IntPtr.Zero))
                        {
                            var hSrcDc = src.GetHdc();
                            var hDc = dest.GetHdc();
                            BitBlt(hDc, 0, 0, realRectangle.Width, realRectangle.Height, hSrcDc, realRectangle.X,
                                   realRectangle.Y, (int)CopyPixelOperation.SourceCopy);
                            dest.ReleaseHdc();
                            src.ReleaseHdc();
                        }
                    }

                    WindowsApi.WriteLog($"{nameof(InnerScreenCapture)} {nameof(realRectangle)}:{realRectangle}");

                    return screenPixel;
                }, cancellationToken));
            }
            else
            {
                WindowsApi.WriteLog($"{nameof(InnerScreenCapture)} failed. {nameof(realRectangle)}:{realRectangle}");

                throw new InvalidOperationException(
                          $"Can't capture from {nameof(realRectangle)} is {realRectangle}");
            }
        }
Exemple #23
0
        /// <summary>
        /// Surf match
        /// </summary>
        /// <param name="wantBitmap">Want match bitmap</param>
        /// <param name="bitmap">target bitmap</param>
        /// <param name="surfMatch">surf match option</param>
        /// <param name="cancellationToken">cancellationToken</param>
        /// <returns>Target bitmap location</returns>
        private async Task <Rectangle?> SurfMatchLocation(Bitmap wantBitmap, Bitmap bitmap, SurfMatch surfMatch,
                                                          CancellationToken cancellationToken)
        {
            return(await Task.Run(() =>
            {
                try
                {
                    using (var matSrc = bitmap.ToMat())
                        using (var matTo = wantBitmap.ToMat())
                            using (var matSrcRet = new Mat())
                                using (var matToRet = new Mat())
                                {
                                    cancellationToken.ThrowIfCancellationRequested();

                                    KeyPoint[] keyPointsSrc, keyPointsTo;
                                    using (var surf = SURF.Create(surfMatch.HessianThreshold, 4, 3, true, true))
                                    {
                                        surf.DetectAndCompute(matSrc, null, out keyPointsSrc, matSrcRet);
                                        surf.DetectAndCompute(matTo, null, out keyPointsTo, matToRet);
                                    }

                                    cancellationToken.ThrowIfCancellationRequested();

                                    using (var flnMatcher = new FlannBasedMatcher())
                                    {
                                        var matches = flnMatcher.Match(matSrcRet, matToRet);

                                        cancellationToken.ThrowIfCancellationRequested();

                                        //求最小最大距离
                                        var minDistance = 1000d; //反向逼近
                                        var maxDistance = 0d;
                                        for (int i = 0; i < matSrcRet.Rows; i++)
                                        {
                                            var distance = matches[i].Distance;
                                            if (distance > maxDistance)
                                            {
                                                maxDistance = distance;
                                            }

                                            if (distance < minDistance)
                                            {
                                                minDistance = distance;
                                            }
                                        }

                                        var pointsSrc = new List <Point2f>();
                                        var pointsDst = new List <Point2f>();

                                        for (int i = 0; i < matSrcRet.Rows; i++)
                                        {
                                            double distance = matches[i].Distance;
                                            if (distance < Math.Max(minDistance * 2, 0.02))
                                            {
                                                pointsSrc.Add(keyPointsSrc[matches[i].QueryIdx].Pt);
                                                pointsDst.Add(keyPointsTo[matches[i].TrainIdx].Pt);
                                            }
                                        }

                                        if (pointsSrc.Count > 0 && pointsDst.Count > 0)
                                        {
                                            var location = pointsSrc[0] - pointsDst[0];

                                            var rectangle =
                                                new Rectangle?(new Rectangle((int)location.X, (int)location.Y, wantBitmap.Width,
                                                                             wantBitmap.Height));
                                            WindowsApi.WriteLog(
                                                $"{nameof(SurfMatchLocation)} match success, {nameof(maxDistance)}:{maxDistance};{nameof(minDistance)}:{minDistance} match count:{pointsSrc.Count}, {rectangle}");

                                            return rectangle;
                                        }
                                        else
                                        {
                                            WindowsApi.WriteLog(
                                                $"{nameof(SurfMatchLocation)} match failed, {nameof(maxDistance)}:{maxDistance};{nameof(minDistance)}:{minDistance}");
                                        }
                                    }
                                }
                }
                catch (Exception ex)
                {
                    WindowsApi.WriteLog($"{nameof(SurfMatchLocation)} ErrorMessage:{ex.Message}");
                }

                return null;
            }, cancellationToken));
        }
Exemple #24
0
        /// <summary>
        /// Sift match
        /// </summary>
        /// <param name="wantBitmap">Want match bitmap</param>
        /// <param name="bitmap">target bitmap</param>
        /// <param name="cancellationToken">cancellationToken</param>
        /// <returns>Target bitmap location</returns>
        private async Task <Rectangle?> SiftMatchLocation(Bitmap wantBitmap, Bitmap bitmap,
                                                          CancellationToken cancellationToken)
        {
            return(await Task.Run(() =>
            {
                try
                {
                    using var matSrc = bitmap.ToMat();
                    using var matTo = wantBitmap.ToMat();
                    using var matSrcRet = new Mat();
                    using var matToRet = new Mat();

                    cancellationToken.ThrowIfCancellationRequested();

                    KeyPoint[] keyPointsSrc, keyPointsTo;
                    using (var sift = SIFT.Create())
                    {
                        sift.DetectAndCompute(matSrc, null, out keyPointsSrc, matSrcRet);
                        sift.DetectAndCompute(matTo, null, out keyPointsTo, matToRet);
                    }

                    cancellationToken.ThrowIfCancellationRequested();

                    using (var bfMatcher = new BFMatcher())
                    {
                        var matches = bfMatcher.KnnMatch(matSrcRet, matToRet, k: 2);

                        cancellationToken.ThrowIfCancellationRequested();

                        var pointsSrc = new List <Point2f>();
                        var pointsDst = new List <Point2f>();
                        foreach (var items in matches.Where(x => x.Length > 1))
                        {
                            if (items[0].Distance < 0.5 * items[1].Distance)
                            {
                                pointsSrc.Add(keyPointsSrc[items[0].QueryIdx].Pt);
                                pointsDst.Add(keyPointsTo[items[0].TrainIdx].Pt);
                            }
                        }

                        if (pointsSrc.Count > 0 && pointsDst.Count > 0)
                        {
                            var location = pointsSrc[0] - pointsDst[0];

                            var rectangle =
                                new Rectangle?(new Rectangle((int)location.X, (int)location.Y, wantBitmap.Width,
                                                             wantBitmap.Height));
                            WindowsApi.WriteLog(
                                $"{nameof(SiftMatchLocation)} match success, match count:{pointsSrc.Count}, {rectangle}");

                            return rectangle;
                        }
                        else
                        {
                            WindowsApi.WriteLog(
                                $"{nameof(SiftMatchLocation)} match failed");
                        }
                    }
                }
                catch (Exception ex)
                {
                    WindowsApi.WriteLog($"{nameof(SiftMatchLocation)} ErrorMessage:{ex.Message}");
                }

                return null;
            }, cancellationToken));
        }