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; } }
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"); } }
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); }
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; } }
public void OnPreviewFrame(IntPtr data, Camera camera) { using (var fastArray = new FastJavaByteArray(data)) { OnPreviewFrameReady?.Invoke(this, fastArray); camera.AddCallbackBuffer(fastArray); } }
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 { } }
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); }
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); } } }
/// <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; }
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; } }