void DecodeFrame(FastJavaByteArray fastArray)
        {
            var resolution = cameraController.CameraResolution;
            var width      = resolution.Width;
            var height     = resolution.Height;

            var rotate    = false;
            var newWidth  = width;
            var newHeight = height;

            // use last value for performance gain
            var cDegrees = cameraController.LastCameraDisplayOrientationDegree;

            if (cDegrees == 90 || cDegrees == 270)
            {
                rotate    = true;
                newWidth  = height;
                newHeight = width;
            }

            var start = PerformanceCounter.Start();

            LuminanceSource fast = new FastJavaByteArrayYUVLuminanceSource(fastArray, width, height, 0, 0, width, height); // _area.Left, _area.Top, _area.Width, _area.Height);

            if (rotate)
            {
                fast = fast.rotateCounterClockwise();
            }

            var result = barcodeReader.Decode(fast);

            fastArray.Dispose();
            fastArray = null;

            PerformanceCounter.Stop(start,
                                    "Decode Time: {0} ms (width: " + width + ", height: " + height + ", degrees: " + cDegrees + ", rotate: " +
                                    rotate + ")");

            if (result != null)
            {
                // Convert LuminanceSource to grey-scale Bitmap array
                var grayscale_image = fast.Matrix;

                var imageBytes = new byte[fast.Width, fast.Height];
                for (var y = 0; y < fast.Height; y++)
                {
                    for (var x = 0; x < fast.Width; x++)
                    {
                        var value = grayscale_image[y * fast.Width + x];
                        imageBytes[x, y] = value;
                    }
                }

                Android.Util.Log.Debug(MobileBarcodeScanner.TAG, "Barcode Found");

                wasScanned = true;
                BarcodeFound?.Invoke(new ScanResult(result, imageBytes));
                return;
            }
        }
Beispiel #2
0
 public static void BlockCopyTo(this FastJavaByteArray self, int sourceIndex, byte[] array, int arrayIndex, int length)
 {
     unsafe
     {
         Marshal.Copy(new IntPtr(self.Raw + sourceIndex), array, arrayIndex, Math.Min(length, Math.Min(self.Count, array.Length - arrayIndex)));
     }
 }
        private void DecodeFrame(FastJavaByteArray fastArray)
        {
            var cameraParameters = _cameraController.Camera.GetParameters();
            var width            = cameraParameters.PreviewSize.Width;
            var height           = cameraParameters.PreviewSize.Height;

            var barcodeReader = _scannerHost.ScanningOptions.BuildBarcodeReader();

            var rotate    = false;
            var newWidth  = width;
            var newHeight = height;

            // use last value for performance gain
            var cDegrees = _cameraController.LastCameraDisplayOrientationDegree;

            //if (cDegrees == 90 || cDegrees == 270)
            //{
            //    rotate = true;
            //    newWidth = height;
            //    newHeight = width;
            //}

            ZXing.Result result = null;
            var          start  = PerformanceCounter.Start();

            //LuminanceSource fast = new FastJavaByteArrayYUVLuminanceSource(fastArray, width, height, 0, 0, width, height); // _area.Left, _area.Top, _area.Width, _area.Height);
            // cut square in the middle
            LuminanceSource fast = new FastJavaByteArrayYUVLuminanceSource(
                fastArray,
                width,
                height,
                (width - Math.Min(width, height)) / 2,
                (height - Math.Min(width, height)) / 2,
                Math.Min(width, height),
                Math.Min(width, height)
                );

            if (rotate)
            {
                fast = fast.rotateCounterClockwise();
            }

            result = barcodeReader.Decode(fast);

            fastArray.Dispose();
            fastArray = null;

            PerformanceCounter.Stop(start,
                                    "Decode Time: {0} ms (width: " + width + ", height: " + height + ", degrees: " + cDegrees + ", rotate: " +
                                    rotate + ")");

            if (result != null)
            {
                Android.Util.Log.Debug(MobileBarcodeScanner.TAG, "Barcode Found: " + result.Text);

                _wasScanned = true;
                BarcodeFound?.Invoke(this, result);
                return;
            }
        }
        protected override void OnElementChanged(ElementChangedEventArgs <AR_Sudoku_Solver.CameraPreview> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                cameraPreview = new CameraPreview(Context);
                SetNativeControl(cameraPreview);
            }

            if (e.OldElement != null)
            {
                // Unsubscribe
                cameraPreview.Click -= OnCameraPreviewClicked;
            }
            if (e.NewElement != null)
            {
                Control.Preview = Camera.Open((int)e.NewElement.Camera);
                var parameters = Control.Preview.GetParameters();
                parameters.FocusMode = Camera.Parameters.FocusModeContinuousPicture;
                Control.Preview.SetParameters(parameters);

                int numBytes = (parameters.PreviewSize.Width * parameters.PreviewSize.Height * Android.Graphics.ImageFormat.GetBitsPerPixel(parameters.PreviewFormat)) / 8;
                using (FastJavaByteArray buffer = new FastJavaByteArray(numBytes))
                {
                    // allocate new Java byte arrays for Android to use for preview frames
                    Control.Preview.AddCallbackBuffer(new FastJavaByteArray(numBytes));
                }

                Control.Preview.SetNonMarshalingPreviewCallback(new AndroidImagePreviewCallbackHandler(e.NewElement.ImageHandlerCallback, cameraPreview));
                // Subscribe
                cameraPreview.Click += OnCameraPreviewClicked;
            }
        }
        private void HandleOnPreviewFrameReady(object sender, FastJavaByteArray fastArray)
        {
            if (!CanAnalyzeFrame)
            {
                return;
            }

            _wasScanned          = false;
            _lastPreviewAnalysis = DateTime.UtcNow;

            _processingTask = Task.Run(() =>
            {
                try
                {
                    DecodeFrame(fastArray);
                } catch (Exception ex) {
                    Console.WriteLine(ex);
                }
            }).ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    Android.Util.Log.Debug(MobileBarcodeScanner.TAG, "DecodeFrame exception occurs");
                }
            }, TaskContinuationOptions.OnlyOnFaulted);
        }
        public void SetupCamera()
        {
            if (Camera != null)
            {
                return;
            }

            var perf = PerformanceCounter.Start();

            OpenCamera();
            PerformanceCounter.Stop(perf, "Setup Camera took {0}ms");

            if (Camera == null)
            {
                return;
            }

            perf = PerformanceCounter.Start();
            ApplyCameraSettings();

            try
            {
                Camera.SetPreviewDisplay(holder);


                var previewParameters = Camera.GetParameters();
                var previewSize       = previewParameters.PreviewSize;
                var bitsPerPixel      = ImageFormat.GetBitsPerPixel(previewParameters.PreviewFormat);


                var       bufferSize          = (previewSize.Width * previewSize.Height * bitsPerPixel) / 8;
                const int NUM_PREVIEW_BUFFERS = 5;
                for (uint i = 0; i < NUM_PREVIEW_BUFFERS; ++i)
                {
                    using (var buffer = new FastJavaByteArray(bufferSize))
                        Camera.AddCallbackBuffer(buffer);
                }

                Camera.StartPreview();

                Camera.SetNonMarshalingPreviewCallback(cameraEventListener);

                // Docs suggest if Auto or Macro modes, we should invoke AutoFocus at least once
                var currentFocusMode = Camera.GetParameters().FocusMode;
                if (currentFocusMode == Camera.Parameters.FocusModeAuto ||
                    currentFocusMode == Camera.Parameters.FocusModeMacro)
                {
                    AutoFocus();
                }
            }
            catch (Exception ex)
            {
                Android.Util.Log.Debug(MobileBarcodeScanner.TAG, ex.ToString());
                return;
            }
            finally
            {
                PerformanceCounter.Stop(perf, "Setup Camera Parameters took {0}ms");
            }
        }
Beispiel #7
0
        private void HandleOnPreviewFrameReady(object sender, FastJavaByteArray fastArray)
        {
            cameraFPSCounter.Report();

            if (!CanAnalyzeFrame)
            {
                return;
            }

            processingFPSCounter.Report();

            processingTask = Task.Run(() =>
            {
                try
                {
                    DecodeFrame(fastArray);
                } catch (Exception ex) {
                    Console.WriteLine(ex);
                }
            }).ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    Debug.WriteLine("DecodeFrame exception occurs");
                }
            }, TaskContinuationOptions.OnlyOnFaulted);
        }
Beispiel #8
0
        private void DecodeFrame(FastJavaByteArray fastArray)
        {
            var cameraParameters = _cameraController.Camera.GetParameters();
            var width            = cameraParameters.PreviewSize.Width;
            var height           = cameraParameters.PreviewSize.Height;

            InitBarcodeReaderIfNeeded();

            var rotate    = false;
            var newWidth  = width;
            var newHeight = height;

            // use last value for performance gain
            var cDegrees = _cameraController.LastCameraDisplayOrientationDegree;

            if (cDegrees == 90 || cDegrees == 270)
            {
                rotate    = true;
                newWidth  = height;
                newHeight = width;
            }

            ZXing.Result result = null;
            var          start  = PerformanceCounter.Start();

            LuminanceSource luminanceSource;

            var fast = new FastJavaByteArrayYUVLuminanceSource(fastArray, width, height, 0, 0, width, height); // _area.Left, _area.Top, _area.Width, _area.Height);

            if (rotate)
            {
                fast.CopyMatrix(ref _matrix);
                RotateCounterClockwise(_matrix, ref _rotatedMatrix, width, height);                                        // _area.Width, _area.Height);
                luminanceSource = new PlanarYUVLuminanceSource(_rotatedMatrix, height, width, 0, 0, height, width, false); // _area.Height, _area.Width, 0, 0, _area.Height, _area.Width, false);
            }
            else
            {
                luminanceSource = fast;
            }

            result = _barcodeReader.Decode(luminanceSource);

            fastArray.Dispose();
            fastArray = null;

            PerformanceCounter.Stop(start,
                                    "Decode Time: {0} ms (width: " + width + ", height: " + height + ", degrees: " + cDegrees + ", rotate: " +
                                    rotate + ")");

            if (result != null)
            {
                Android.Util.Log.Debug(MobileBarcodeScanner.TAG, "Barcode Found: " + result.Text);

                _wasScanned = true;
                BarcodeFound?.Invoke(this, result);
                return;
            }
        }
Beispiel #9
0
        public void OnPreviewFrame(IntPtr data, Camera camera)
        {
            using (var fastArray = new FastJavaByteArray(data))
            {
                OnPreviewFrameReady?.Invoke(this, fastArray);

                camera.AddCallbackBuffer(fastArray);
            }
        }
Beispiel #10
0
        public void SetupCamera()
        {
            if (camera != null)
            {
                return;
            }

            PermissionsHandler.CheckCameraPermissions(context);

            OpenCamera();

            if (camera == null)
            {
                return;
            }

            ApplyCameraSettings();

            try
            {
                camera.SetPreviewDisplay(holder);

                var previewParameters = camera.GetParameters();
                var previewSize       = previewParameters.PreviewSize;
                var bitsPerPixel      = ImageFormat.GetBitsPerPixel(previewParameters.PreviewFormat);

                int       bufferSize          = (previewSize.Width * previewSize.Height * bitsPerPixel) / 8;
                const int NUM_PREVIEW_BUFFERS = 5;
                for (uint i = 0; i < NUM_PREVIEW_BUFFERS; ++i)
                {
                    using (var buffer = new FastJavaByteArray(bufferSize))
                        camera.AddCallbackBuffer(buffer);
                }

                camera.StartPreview();

                camera.SetNonMarshalingPreviewCallback(cameraEventListener);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
                return;
            }
            finally
            {
            }
        }
Beispiel #11
0
        void DecodeFrame(FastJavaByteArray fastArray)
        {
            var resolution = cameraController.CameraResolution;
            var width      = resolution.Width;
            var height     = resolution.Height;

            var rotate    = false;
            var newWidth  = width;
            var newHeight = height;

            // use last value for performance gain
            var cDegrees = cameraController.LastCameraDisplayOrientationDegree;

            if (cDegrees == 90 || cDegrees == 270)
            {
                rotate    = true;
                newWidth  = height;
                newHeight = width;
            }

            var start = PerformanceCounter.Start();

            LuminanceSource fast = new FastJavaByteArrayYUVLuminanceSource(fastArray, width, height, 0, 0, width, height);             // _area.Left, _area.Top, _area.Width, _area.Height);

            if (rotate)
            {
                fast = fast.rotateCounterClockwise();
            }

            var result = barcodeReader.Decode(fast);

            fastArray.Dispose();
            fastArray = null;

            PerformanceCounter.Stop(start,
                                    "Decode Time: {0} ms (width: " + width + ", height: " + height + ", degrees: " + cDegrees + ", rotate: " +
                                    rotate + ")");

            if (result != null)
            {
                Android.Util.Log.Debug(MobileBarcodeScanner.TAG, "Barcode Found");

                wasScanned = true;
                BarcodeFound?.Invoke(result);
                return;
            }
        }
        private void HandleOnPreviewFrameReady(object sender, FastJavaByteArray fastArray)
        {
            if (!CanAnalyzeFrame)
            {
                return;
            }

            _wasScanned          = false;
            _lastPreviewAnalysis = DateTime.UtcNow;

            _processingTask = Task.Run(() =>
            {
                try
                {
                    if (TakePicture)
                    {
                        TakePicture = false;
                        var raw     = new byte[fastArray.Count];
                        fastArray.CopyTo(raw, 0);
                        var img = new YuvImage(raw, ImageFormatType.Nv21, _cameraController.Camera.GetParameters().PreviewSize.Width, _cameraController.Camera.GetParameters().PreviewSize.Height, null);
                        using (var stream = new MemoryStream())
                        {
                            var rect = new Rect(0, 0, img.Width, img.Height);
                            img.CompressToJpeg(rect, 80, stream);
                            var array = stream.ToArray();
                            OnPictureTaken?.Invoke(this, array);
                            stream.Close();
                        }
                    }


                    DecodeFrame(fastArray);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }).ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    Android.Util.Log.Debug(MobileBarcodeScanner.TAG, "DecodeFrame exception occurs");
                }
            }, TaskContinuationOptions.OnlyOnFaulted);
        }
Beispiel #13
0
        public static byte[] ConvertToJpg(this FastJavaByteArray self, int width, int height)
        {
            byte[] javaByteArray = new byte[self.Count];
            self.CopyTo(javaByteArray, 0);

            using (YuvImage yuvImage = new YuvImage(javaByteArray, ImageFormatType.Nv21, width, height, null))
            {
                using (Rect rect = new Rect(0, 0, width, height))
                {
                    byte[] jpg = null;
                    using (var os = new MemoryStream())
                    {
                        yuvImage.CompressToJpeg(rect, 100, os);
                        jpg = os.ToArray();
                        os.Close();
                    }
                    return(jpg);
                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PlanarYUVLuminanceSource"/> class.
        /// </summary>
        /// <param name="yuvData">The yuv data.</param>
        /// <param name="dataWidth">Width of the data.</param>
        /// <param name="dataHeight">Height of the data.</param>
        /// <param name="left">The left.</param>
        /// <param name="top">The top.</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="reverseHoriz">if set to <c>true</c> [reverse horiz].</param>
        public FastJavaByteArrayYUVLuminanceSource(FastJavaByteArray yuv,
                                                   int dataWidth,
                                                   int dataHeight,
                                                   int left,
                                                   int top,
                                                   int width,
                                                   int height)
            : base(width, height)
        {
            if (left < 0)
            {
                throw new ArgumentException("Negative value", nameof(left));
            }

            if (top < 0)
            {
                throw new ArgumentException("Negative value", nameof(top));
            }

            if (width < 0)
            {
                throw new ArgumentException("Negative value", nameof(width));
            }

            if (height < 0)
            {
                throw new ArgumentException("Negative value", nameof(height));
            }

            if (left + width > dataWidth || top + height > dataHeight)
            {
                throw new ArgumentException("Crop rectangle does not fit within image data.");
            }

            _yuv        = yuv;
            _dataWidth  = dataWidth;
            _dataHeight = dataHeight;
            _left       = left;
            _top        = top;
        }
Beispiel #15
0
        private unsafe void DecodeFrame(FastJavaByteArray fastArray)
        {
            if (input == null)
            {
                width    = cameraController.LastCameraDisplayWidth;
                height   = cameraController.LastCameraDisplayHeight;
                cDegrees = cameraController.LastCameraDisplayOrientationDegree;

                imageData     = new int[width * height];
                imageGCHandle = GCHandle.Alloc(imageData, GCHandleType.Pinned);
                imageIntPtr   = imageGCHandle.AddrOfPinnedObject();

                input = new SKBitmap(new SKImageInfo(width, height, SKColorType.Rgba8888));
                input.InstallPixels(input.Info, imageIntPtr);
            }

            var pY  = fastArray.Raw;
            var pUV = pY + width * height;

            stopwatch.Restart();
            YuvHelper.ConvertYUV420SPToARGB8888(pY, pUV, (int *)imageIntPtr, width, height);
            stopwatch.Stop();
            Stats.YUV2RGBElapsedMs = stopwatch.ElapsedMilliseconds;

            stopwatch.Restart();
            input.ScalePixels(inputScaled, SKFilterQuality.None);
            RotateBitmap(inputScaled, cDegrees);
            stopwatch.Stop();
            Stats.ResizeAndRotateElapsedMs = stopwatch.ElapsedMilliseconds;

            stopwatch.Restart();
            tfService.Recognize(colors, colorCount);
            stopwatch.Stop();
            Stats.InterpreterElapsedMs = stopwatch.ElapsedMilliseconds;

            MainActivity.ReloadCanvas();
        }
        public unsafe void OnPreviewFrame(IntPtr data, Camera camera)
        {
            if (!isSizeSet)
            {
                height = camera.GetParameters().PreviewSize.Height;
                width  = camera.GetParameters().PreviewSize.Width;
                StaticSKInfo.iheight = height;
                StaticSKInfo.iwidth  = width;
                StaticSKInfo.sheight = camerapreview.surfaceView.Height;
                StaticSKInfo.swidth  = camerapreview.surfaceView.Width;
                isSizeSet            = true;
            }

            using (FastJavaByteArray buffer = new FastJavaByteArray(data))
            {
                StaticSKInfo.iheight = height;
                StaticSKInfo.iwidth  = width;
                StaticSKInfo.sheight = camerapreview.surfaceView.Height;
                StaticSKInfo.swidth  = camerapreview.surfaceView.Width;
                gray = new Mat(height, width, MatType.CV_8UC1, (IntPtr)buffer.Raw);
                if (sf.FindSudoku(gray))
                {
                    StaticSKInfo.bitmap.SetPixels(sf.unwarpedSudoku.Clone().DataStart);
                    StaticSKInfo.centres     = sf.centres;
                    StaticSKInfo.corners     = sf.corners;
                    StaticSKInfo.drawCorners = true;
                    if (!runningLongProcessing)
                    {
                        Task processingTask = new Task(LongImageProcessing);
                        processingTask.Start();
                    }
                }
                previewHandler.GotNewImageCB();
                camera.AddCallbackBuffer(buffer);
            }
        }
        private void DecodeFrame(FastJavaByteArray fastArray)
        {
            var cameraParameters = _cameraController.Camera.GetParameters();
            var width            = cameraParameters.PreviewSize.Width;
            var height           = cameraParameters.PreviewSize.Height;

            var barcodeReader = _scannerHost.ScanningOptions.BuildBarcodeReader();

            var rotate    = false;
            var newWidth  = width;
            var newHeight = height;

            // use last value for performance gain
            var cDegrees = _cameraController.LastCameraDisplayOrientationDegree;

            if (cDegrees == 90 || cDegrees == 270)
            {
                rotate    = true;
                newWidth  = height;
                newHeight = width;
            }

            ZXing.Result result = null;
            var          start  = PerformanceCounter.Start();

            /// <summary>
            ///START - Scanning Improvement, VK Apacheta Corp 11/14/2018
            ///Added a new frame to get the center part of the captured image.
            ///To create a FastJavaByteArray from the cropped captured frame and use it to decode the barcode.
            ///To decrease the processing time drastically for higher resolution cameras.
            /// </summary>
            var frame_width  = width * 3 / 5;
            var frame_height = height * 3 / 5;
            var frame_left   = width * 1 / 5;
            var frame_top    = height * 1 / 5;

            LuminanceSource fast = new FastJavaByteArrayYUVLuminanceSource(fastArray, width, height,
                                                                           //framingRectPreview?.Width() ?? width,
                                                                           // framingRectPreview?.Height() ?? height,
                                                                           frame_left,
                                                                           frame_top,
                                                                           frame_width,
                                                                           frame_height);  // _area.Left, _area.Top, _area.Width, _area.Height);

            /// <summary>
            ///END - Scanning Improvement, VK Apacheta Corp 11/14/2018
            /// </summary>
            if (rotate)
            {
                fast = fast.rotateCounterClockwise();
            }

            result = barcodeReader.Decode(fast);

            fastArray.Dispose();
            fastArray = null;

            PerformanceCounter.Stop(start,
                                    $"width: {width}, height: {height}, frame_top :{frame_top}, frame_left: {frame_left}, frame_width: {frame_width}, frame_height: {frame_height}, degrees: {cDegrees}, rotate: {rotate}; " + "Decode Time: {0} ms");

            if (result != null)
            {
                Log.Debug(MobileBarcodeScanner.TAG, "Barcode Found");

                _wasScanned = true;
                BarcodeFound?.Invoke(this, result);
                return;
            }
        }
        void DecodeFrame(FastJavaByteArray fastArray)
        {
            var rotate = DeviceDisplay.MainDisplayInfo.Orientation == DisplayOrientation.Portrait;
            var start  = PerformanceCounter.Start();

            //only calculate the variables needed for decoding if the camera is rotated or the CustomScanAreaView (if used) is changed
            if (lastDecodedCameraDisplayRotationDegree != cameraController.CurrentCameraDisplayRotationDegree || needRecalculateDecodingVariables)
            {
                if (surfaceView != null && surfaceView.UsingCustomScanArea)
                {
                    SetDecodeVariablesForCustomScanArea();
                }
                else
                {
                    SetDecodeVariablesForWholeScreen();
                }

                lastDecodedCameraDisplayRotationDegree = cameraController.CurrentCameraDisplayRotationDegree;
                needRecalculateDecodingVariables       = false;
            }

            var             barcodeReader = scannerHost.ScanningOptions.BuildBarcodeReader();
            LuminanceSource fast;

            if (rotate)
            {
                //for decoding it is expected that the FastJavaByteArrayYUVLuminanceSource will be in landscape orientation
                //if we are in portrait mode the array must be rotated
                //also since we are in portrait mode and all dimensions are calculated from the perspective of the user they must be
                //given to the constructor flipped
                fast = new FastJavaByteArrayYUVLuminanceSource(fastArray, heightCamera, widthCamera,
                                                               offsetScanAreaTopPixelsScaled,
                                                               offsetScanAreaLeftPixelsScaled,
                                                               heightScanAreaScaled,
                                                               widthScanAreaScaled).rotateCounterClockwise();
            }
            else
            {
                //while in landscape mode the FastJavaByteArrayYUVLuminanceSource paramater names match up with the names of the calculated values
                fast = new FastJavaByteArrayYUVLuminanceSource(fastArray, widthCamera, heightCamera,
                                                               offsetScanAreaLeftPixelsScaled,
                                                               offsetScanAreaTopPixelsScaled,
                                                               widthScanAreaScaled,
                                                               heightScanAreaScaled);
            }


            var result = barcodeReader.Decode(fast);

            fastArray.Dispose();
            fastArray = null;

            PerformanceCounter.Stop(start,
                                    "Decode Time: {0} ms (width: " + widthCamera + ", height: " + heightCamera + ", degrees: " + lastDecodedCameraDisplayRotationDegree + ", rotate: " +
                                    rotate + ")");

            if (result != null)
            {
                Android.Util.Log.Debug(MobileBarcodeScanner.TAG, "Barcode Found");
                wasScanned = true;
                BarcodeFound?.Invoke(result);
                return;
            }
        }