Пример #1
0
        public async UnaryResult <Nil> ReportScreenshot(Bgra32Image screenshot, DateTimeOffset timestamp)
        {
            using (screenshot)
            {
                if (this.IsScreenshotEnabled)
                {
                    var workerId = await this.WorkerInitializeAsync().ConfigureAwait(false);

                    await this.RetryWhenLocked(() =>
                    {
                        this.Connection.InsertOrReplace(new WorkerScreenshot()
                        {
                            WorkerId          = workerId,
                            Width             = screenshot.Width,
                            Height            = screenshot.Height,
                            Data              = screenshot.Data.ToArray(),
                            TimestampOnWorker = timestamp,
                            TimestampOnServer = DateTimeOffset.Now,
                        });
                    }).ConfigureAwait(false);
                }
            }

            return(Nil.Default);
        }
Пример #2
0
        private async Task UpdateScreen()
        {
            var source = this.imgScreen.Source as WriteableBitmap;

            var img = await this._connection.CaptureContentAsync();

            this._screenImage?.Dispose();
            this._screenImage = img;

            var createNewBitmap = source == null || source.PixelWidth != img.Width || source.PixelHeight != img.Height;

            if (createNewBitmap)
            {
                source = new WriteableBitmap(img.Width, img.Height, 96, 96, PixelFormats.Bgr32, null);
            }

            source.Lock();
            try
            {
                CopyPixels(img, source.BackBuffer, source.BackBufferStride * source.PixelHeight);
                source.AddDirtyRect(new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight));
            }
            finally
            {
                source.Unlock();
            }

            this.BindingModel.GameWidth  = img.Width;
            this.BindingModel.GameHeight = img.Height;

            if (createNewBitmap)
            {
                this.imgScreen.Source = source;
            }
        }
Пример #3
0
            public static Bgra32Image CreateDiff(Bgra32Image a, Bgra32Image b, int tolerance)
            {
                Debug.Assert(a.W == b.W && a.H == b.H);
                var diff = new Bgra32Image(null, a.W, a.H);

                diff.RefreshDiffAsync(a, b, tolerance);
                return(diff);
            }
Пример #4
0
        public Bgr2432InputImage(Bgra32Image image)
        {
            this._image = image;
            var data = image.Data;

            this._data   = data.Array;
            this._offset = data.Offset;
        }
Пример #5
0
        private async Task UpdateCursorImage()
        {
            if (this._connection == null)
            {
                return;
            }

            try
            {
                var  source = this.imgCursor.Source as WriteableBitmap;
                bool createNewBitmap;

                var img = await this._connection.GetCursorImageAsync();

                this._cursorImage?.Dispose();
                this._cursorImage = img;

                createNewBitmap = source == null || source.PixelWidth != img.Width || source.PixelHeight != img.Height;
                if (createNewBitmap)
                {
                    source = new WriteableBitmap(img.Width, img.Height, 96, 96, PixelFormats.Pbgra32, null);
                }

                source.Lock();

                try
                {
                    CopyPixels(img, source.BackBuffer, source.BackBufferStride * source.PixelHeight);
                    source.AddDirtyRect(new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight));
                }
                finally
                {
                    source.Unlock();
                }

                if (createNewBitmap)
                {
                    this.imgCursor.Source = source;
                }
            }
            catch (Exception ex)
            {
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }

                this._connection = null;
                MessageBox.Show(this, ex.ToString(), "エラー", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Пример #6
0
        public bool IsMatch(Bgra32Image cursorImage)
        {
            if (cursorImage.Width != ExpectedSize || cursorImage.Height != ExpectedSize)
            {
                return(false);
            }

            var pixels = MemoryMarshal.Cast <byte, uint>((ReadOnlySpan <byte>)cursorImage.Data);

            for (var y = 0; y < ExpectedSize; y++)
            {
                uint lineBitmap = 0;
                uint lineMask   = 0;

                for (var x = 0; x < ExpectedSize; x++)
                {
                    var pixel = pixels[y * ExpectedSize + x];

                    // Alpha が 0 ならば透明と判断
                    var isTransparent = (pixel & 0xff000000) == 0;

                    if (!isTransparent)
                    {
                        lineMask |= 0b1000_0000_0000_0000u >> x;

                        // 真っ白でなければ色がついていると判断
                        var isColored = (pixel & 0x00ffffff) != 0x00ffffff;
                        if (isColored)
                        {
                            lineBitmap |= 0b1000_0000_0000_0000u >> x;
                        }
                    }
                }

                uint expectedMask = this.Mask[y];
                if (lineMask != expectedMask)
                {
                    return(false);
                }
                if (lineBitmap != (this.Bitmap[y] & expectedMask))
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #7
0
        public void SetImages(BitmapSource left, BitmapSource right, int tolerance)
        {
            // check tolerance
            if (tolerance < 0 || tolerance > 255)
            {
                ErrorLogLine("Tolerance must be integer from 0 to 255");
                return;
            }

            // Load images
            int w      = Math.Max(left.PixelWidth, right.PixelWidth);
            int h      = Math.Max(left.PixelHeight, right.PixelHeight);
            var image1 = GetImage2D(left, w, h);
            var image2 = GetImage2D(right, w, h);
            var imaged = new Bgra32Image(null, w, h);

            if (null == image1 || null == image2)
            {
                return;
            }

            // done
            this.leftImage  = image1;
            this.rightImage = image2;
            if (null != this.diffImage)
            {
                this.diffImage.GenDiffComplete -= DiffImage_GenDiffComplete;
            }
            this.diffImage = new Bgra32Image(null, w, h);
            if (null != this.diffImage)
            {
                this.diffImage.GenDiffComplete += DiffImage_GenDiffComplete;
            }
            this.leftThumbnail.Source  = this.leftImage.ImageSource;
            this.rightThumbnail.Source = this.rightImage.ImageSource;
            this.diffThumbnail.Source  = this.diffImage.ImageSource;
            SwitchMainImage(MainImageType.DIFF);
            RefreshDiffImage(tolerance);
        }
Пример #8
0
 /// <summary>
 /// スクリーンショットを送信します。
 /// </summary>
 public abstract Task ReportScreenshotAsync(Bgra32Image screenshot, DateTimeOffset timestamp);
Пример #9
0
            public void RefreshDiffAsync(Bgra32Image a, Bgra32Image b, int tolerance)
            {
                // do some basic check
                Debug.Assert(a.W == b.W && a.H == b.H);
                Debug.Assert(a.W == this.W && a.H == this.H);
                if (tolerance < 0)
                {
                    tolerance = 0;
                }
                if (tolerance > 255)
                {
                    tolerance = 255;
                }

#if true
                uint numCpuCores = 8; // TODO: get actual number of cores/processors
                Debug.Assert(this.ImageSource is WriteableBitmap);
                var bmp = this.ImageSource as WriteableBitmap;
                bmp.Lock();
                long stride            = bmp.BackBufferStride;
                bool strideEqualsWidth = (this.W * 4 == stride);
                long buffer            = (long)bmp.BackBuffer;
                Parallel.For(0, numCpuCores, core =>
                {
                    long start = a.Pixels.Length * core / numCpuCores;
                    long end   = a.Pixels.Length * (core + 1) / numCpuCores;
                    for (long i = start; i < end; ++i)
                    {
                        uint actualDiff, diffColor;
                        GetDiff(out actualDiff, out diffColor, a.Pixels[i], b.Pixels[i], tolerance);
                        this.Pixels[i] = actualDiff;
                        if (strideEqualsWidth)
                        {
                            unsafe
                            {
                                ((uint *)buffer)[i] = diffColor;
                            }
                        }
                        else
                        {
                            long x   = i % this.W;
                            long y   = i / this.W;
                            long ptr = buffer + y * stride + x * 4;
                            unsafe
                            {
                                *(uint *)ptr = diffColor;
                            }
                        }
                    }
                });
                bmp.AddDirtyRect(new Int32Rect(0, 0, this.W, this.H));
                bmp.Unlock();
                this.GenDiffComplete(this, tolerance);
#else
                // create a new diff task
                Task task = null;
                task = new Task((object state) =>
                {
                    uint[] diff       = new uint[this.Pixels.Length];
                    uint[] color      = new uint[this.Pixels.Length];
                    int taskTolerance = (int)state;
                    uint numCpuCores  = 8; // TODO: get actual number of core
                    Parallel.For(0, numCpuCores, core =>
                    {
                        long start = a.Pixels.Length * core / numCpuCores;
                        long end   = a.Pixels.Length * (core + 1) / numCpuCores;
                        for (long i = start; i < end; ++i)
                        {
                            if (task != this.genDiffTask)
                            {
                                return;
                            }
                            uint actualDiff, diffColor;
                            GetDiff(out actualDiff, out diffColor, a.Pixels[i], b.Pixels[i], taskTolerance);
                            diff[i]  = actualDiff;
                            color[i] = diffColor;
                        }
                    });
                    Application.Current.Dispatcher.BeginInvoke((Action)(() =>
                    {
                        if (this.genDiffTask == task)
                        {
                            // Update member variables, trigger events, when the task is done.
                            this.Pixels = diff;
                            Debug.Assert(this.ImageSource is WriteableBitmap);
                            (this.ImageSource as WriteableBitmap).WritePixels(new Int32Rect(0, 0, this.W, this.H), color, this.W * 4, 0);
                            this.GenDiffComplete(this, taskTolerance);
                        }
                    }));
                }, tolerance);
                this.genDiffTask = task;
                task.Start();
#endif
            }
Пример #10
0
 public override Task ReportScreenshotAsync(Bgra32Image screenshot, DateTimeOffset timestamp) => this._service.ReportScreenshot(screenshot, timestamp).ResponseAsync;
Пример #11
0
 public override Task ReportScreenshotAsync(Bgra32Image screenshot, DateTimeOffset timestamp)
 {
     return(Task.CompletedTask);
 }
Пример #12
0
 private static unsafe void CopyPixels(Bgra32Image image, IntPtr dest, int destLength)
 {
     ((Span <byte>)image.Data).CopyTo(new Span <byte>((void *)dest, destLength));
 }