Skip to content

Commit

Permalink
2.1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
afriscic committed Dec 4, 2024
1 parent c87a1ec commit fca72c2
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsAotCompatible>true</IsAotCompatible>
<Nullable>enable</Nullable>
<Version>2.1.1</Version>
<Version>2.1.2</Version>
<Authors>Alen Friščić</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
Expand Down
140 changes: 52 additions & 88 deletions BarcodeScanning.Native.Maui/Platform/Android/BarcodeAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
using Xamarin.Google.MLKit.Vision.BarCode;
using Xamarin.Google.MLKit.Vision.Common;

using MLKitBarcodeScanning = Xamarin.Google.MLKit.Vision.BarCode.BarcodeScanning;
using Point = Microsoft.Maui.Graphics.Point;
using Rect = Microsoft.Maui.Graphics.Rect;
using Scanner = Xamarin.Google.MLKit.Vision.BarCode.BarcodeScanning;
using Size = Android.Util.Size;

namespace BarcodeScanning;

internal class BarcodeAnalyzer : Java.Lang.Object, ImageAnalysis.IAnalyzer, IOnSuccessListener, IOnCompleteListener
internal class BarcodeAnalyzer : Java.Lang.Object, ImageAnalysis.IAnalyzer
{
public Size DefaultTargetResolution => Methods.TargetResolution(null);
public int TargetCoordinateSystem => ImageAnalysis.CoordinateSystemViewReferenced;
Expand All @@ -27,9 +27,7 @@ internal class BarcodeAnalyzer : Java.Lang.Object, ImageAnalysis.IAnalyzer, IOnS

private IBarcodeScanner? _barcodeScanner;
private CoordinateTransform? _coordinateTransform;
private IImageProxy? _proxy;

private bool _processInverted = false;
private bool _updateCoordinateTransform = false;
private int _transformDegrees = 0;
private Point _previewViewCenter = new();
Expand All @@ -43,50 +41,39 @@ internal BarcodeAnalyzer(CameraManager cameraManager)

_previewViewRect.X = 0;
_previewViewRect.Y = 0;

UpdateSymbologies();
}

internal void UpdateSymbologies()
{
if (_cameraManager?.CameraView is not null)
{
_barcodeScanner?.Dispose();
_barcodeScanner = MLKitBarcodeScanning.GetClient(new BarcodeScannerOptions.Builder()
.SetBarcodeFormats(Methods.ConvertBarcodeFormats(_cameraManager.CameraView.BarcodeSymbologies))
.Build());
}
_barcodeScanner?.Dispose();
_barcodeScanner = Scanner.GetClient(new BarcodeScannerOptions.Builder()
.SetBarcodeFormats(Methods.ConvertBarcodeFormats(_cameraManager?.CameraView?.BarcodeSymbologies ?? BarcodeFormats.All))
.Build());
}

public void Analyze(IImageProxy proxy)
{
_proxy = proxy;

try
{
ArgumentNullException.ThrowIfNull(_proxy?.Image);
ArgumentNullException.ThrowIfNull(proxy?.Image);
ArgumentNullException.ThrowIfNull(_cameraManager?.CameraView);
ArgumentNullException.ThrowIfNull(_barcodeScanner);

_processInverted = _cameraManager.CameraView.ForceInverted;

if (_cameraManager.CameraView.PauseScanning)
{
CloseProxy();
return;
}

if (_cameraManager.CameraView.CaptureNextFrame)
{
_cameraManager.CameraView.CaptureNextFrame = false;
var image = new PlatformImage(_proxy.ToBitmap());
var image = new PlatformImage(proxy.ToBitmap());
_cameraManager.CameraView.TriggerOnImageCaptured(image);
}

if (_updateCoordinateTransform || _transformDegrees != _proxy.ImageInfo.RotationDegrees)
if (_updateCoordinateTransform || _transformDegrees != proxy.ImageInfo.RotationDegrees)
{
_coordinateTransform = _cameraManager.GetCoordinateTransform(_proxy);
_transformDegrees = _proxy.ImageInfo.RotationDegrees;
_coordinateTransform?.Dispose();
_coordinateTransform = _cameraManager.GetCoordinateTransform(proxy);
_transformDegrees = proxy.ImageInfo.RotationDegrees;

_previewViewCenter.X = _cameraManager.PreviewView.Width / 2;
_previewViewCenter.Y = _cameraManager.PreviewView.Height / 2;
Expand All @@ -96,92 +83,69 @@ public void Analyze(IImageProxy proxy)
_updateCoordinateTransform = false;
}

using var inputImage = InputImage.FromMediaImage(_proxy.Image, _proxy.ImageInfo.RotationDegrees);
_barcodeScanner.Process(inputImage).AddOnSuccessListener(this).AddOnCompleteListener(this);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
CloseProxy();
}
}
using var inputImage = InputImage.FromMediaImage(proxy.Image, proxy.ImageInfo.RotationDegrees);
using var task = _barcodeScanner.Process(inputImage);
var result = TasksClass.Await(task);

Java.Lang.Object? invertedResult = null;
if (_cameraManager.CameraView.ForceInverted)
{
Methods.InvertLuminance(proxy.Image);
using var invertedImage = InputImage.FromMediaImage(proxy.Image, proxy.ImageInfo.RotationDegrees);
using var invertedTask = _barcodeScanner.Process(invertedImage);
invertedResult = TasksClass.Await(invertedTask);
}

public void OnSuccess(Java.Lang.Object? result)
{
try
{
lock (_resultsLock)
{
if (_processInverted == _cameraManager?.CameraView?.ForceInverted)
_barcodeResults.Clear();

if (result is not JavaList javaList)
return;

foreach (Barcode barcode in javaList)
{
if (barcode is null)
continue;
if (string.IsNullOrEmpty(barcode.DisplayValue) && string.IsNullOrEmpty(barcode.RawValue))
continue;

var barcodeResult = barcode.AsBarcodeResult(_coordinateTransform);

if ((_cameraManager?.CameraView?.AimMode ?? false) && !barcodeResult.PreviewBoundingBox.Contains(_previewViewCenter))
continue;
if ((_cameraManager?.CameraView?.ViewfinderMode ?? false) && !_previewViewRect.Contains(barcodeResult.PreviewBoundingBox))
continue;

_barcodeResults.Add(barcodeResult);
}
_barcodeResults.Clear();
AddResultToSet(result);
AddResultToSet(invertedResult);

result?.Dispose();
invertedResult?.Dispose();
}

if (!_processInverted)
_cameraManager?.CameraView?.DetectionFinished(_barcodeResults, _resultsLock);
_cameraManager?.CameraView?.DetectionFinished(_barcodeResults, _resultsLock);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}

public void OnComplete(Android.Gms.Tasks.Task task)
{
if (_processInverted)
finally
{
try
{
_processInverted = false;

ArgumentNullException.ThrowIfNull(_proxy?.Image);
ArgumentNullException.ThrowIfNull(_barcodeScanner);

Methods.InvertLuminance(_proxy.Image);
using var inputImage = InputImage.FromMediaImage(_proxy.Image, _proxy.ImageInfo.RotationDegrees);
_barcodeScanner.Process(inputImage).AddOnSuccessListener(this).AddOnCompleteListener(this);
proxy?.Close();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
CloseProxy();
MainThread.BeginInvokeOnMainThread(() => _cameraManager?.Start());
}
}
else
{
CloseProxy();
}
}

private void CloseProxy()
private void AddResultToSet(Java.Lang.Object? result)
{
try
{
_proxy?.Close();
}
catch (Exception ex)
if (result is not JavaList javaList)
return;

foreach (Barcode barcode in javaList)
{
Debug.WriteLine(ex);
MainThread.BeginInvokeOnMainThread(() => _cameraManager?.Start());
if (barcode is null)
continue;
if (string.IsNullOrEmpty(barcode.DisplayValue) && string.IsNullOrEmpty(barcode.RawValue))
continue;

var barcodeResult = barcode.AsBarcodeResult(_coordinateTransform);

if ((_cameraManager?.CameraView?.AimMode ?? false) && !barcodeResult.PreviewBoundingBox.Contains(_previewViewCenter))
continue;
if ((_cameraManager?.CameraView?.ViewfinderMode ?? false) && !_previewViewRect.Contains(barcodeResult.PreviewBoundingBox))
continue;

_barcodeResults.Add(barcodeResult);
}
}

Expand Down
15 changes: 9 additions & 6 deletions BarcodeScanning.Native.Maui/Platform/Android/CameraManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal class CameraManager : IDisposable
private readonly BarcodeAnalyzer _barcodeAnalyzer;
private readonly BarcodeView _barcodeView;
private readonly Context _context;
private readonly IExecutorService _cameraExecutor;
private readonly IExecutorService _analyzerExecutor;
private readonly ImageView _imageView;
private readonly LifecycleCameraController _cameraController;
private readonly ILifecycleOwner _lifecycleOwner;
Expand Down Expand Up @@ -60,7 +60,7 @@ internal CameraManager(CameraView cameraView, Context context)
ArgumentNullException.ThrowIfNull(owner);
ArgumentNullException.ThrowIfNull(executor);
_lifecycleOwner = owner;
_cameraExecutor = executor;
_analyzerExecutor = executor;

_barcodeAnalyzer = new BarcodeAnalyzer(this);

Expand Down Expand Up @@ -126,9 +126,10 @@ internal void Start()
{
if (OpenedCameraState?.GetType() != CameraState.Type.Closed)
_cameraController.Unbind();

if (_barcodeAnalyzer is not null && _cameraExecutor is not null)
_cameraController.SetImageAnalysisAnalyzer(_cameraExecutor, _barcodeAnalyzer);

_cameraController.ClearImageAnalysisAnalyzer();
if (_barcodeAnalyzer is not null && _analyzerExecutor is not null)
_cameraController.SetImageAnalysisAnalyzer(_analyzerExecutor, _barcodeAnalyzer);

UpdateResolution();
UpdateCamera();
Expand Down Expand Up @@ -269,6 +270,8 @@ protected virtual void Dispose(bool disposing)
_currentCameraInfo?.CameraState.RemoveObserver(_cameraStateObserver);
}

_cameraController?.ClearImageAnalysisAnalyzer();

_barcodeView?.RemoveAllViews();
_relativeLayout?.RemoveAllViews();

Expand All @@ -280,7 +283,7 @@ protected virtual void Dispose(bool disposing)
_currentCameraInfo?.Dispose();
_cameraStateObserver?.Dispose();
_barcodeAnalyzer?.Dispose();
_cameraExecutor?.Dispose();
_analyzerExecutor?.Dispose();
}
}
}
20 changes: 11 additions & 9 deletions BarcodeScanning.Native.Maui/Platform/MaciOS/BarcodeAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,20 @@ internal BarcodeAnalyzer(CameraManager cameraManager)

internal void UpdateSymbologies()
{
if (_cameraManager?.CameraView is not null)
_detectBarcodesRequest.Symbologies = Methods.SelectedSymbologies(_cameraManager.CameraView.BarcodeSymbologies);
_detectBarcodesRequest.Symbologies = Methods.SelectedSymbologies(_cameraManager?.CameraView?.BarcodeSymbologies ?? BarcodeFormats.All);
}

public override void DidOutputSampleBuffer(AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection)
{
try
{
if (_cameraManager?.CameraView?.PauseScanning ?? false)
ArgumentNullException.ThrowIfNull(_cameraManager?.CameraView);
ArgumentNullException.ThrowIfNull(sampleBuffer);

if (_cameraManager.CameraView.PauseScanning)
return;

if (_cameraManager?.CameraView?.CaptureNextFrame ?? false)
if (_cameraManager.CameraView.CaptureNextFrame)
{
_cameraManager.CameraView.CaptureNextFrame = false;
using var imageBuffer = sampleBuffer.GetImageBuffer();
Expand All @@ -69,7 +71,7 @@ public override void DidOutputSampleBuffer(AVCaptureOutput captureOutput, CMSamp
}
}

_sequenceRequestHandler?.Perform([_detectBarcodesRequest], sampleBuffer, out _);
_sequenceRequestHandler.Perform([_detectBarcodesRequest], sampleBuffer, out _);

lock (_resultsLock)
{
Expand All @@ -79,9 +81,9 @@ public override void DidOutputSampleBuffer(AVCaptureOutput captureOutput, CMSamp
if (string.IsNullOrEmpty(barcode.PayloadStringValue))
continue;

var barcodeResult = barcode.AsBarcodeResult(_cameraManager?.PreviewLayer);
var barcodeResult = barcode.AsBarcodeResult(_cameraManager.PreviewLayer);

if (_cameraManager?.CameraView?.AimMode ?? false)
if (_cameraManager.CameraView.AimMode)
{
_previewCenter.X = _cameraManager.PreviewLayer.Bounds.GetMidX();
_previewCenter.Y = _cameraManager.PreviewLayer.Bounds.GetMidY();
Expand All @@ -90,7 +92,7 @@ public override void DidOutputSampleBuffer(AVCaptureOutput captureOutput, CMSamp
continue;
}

if (_cameraManager?.CameraView?.ViewfinderMode ?? false)
if (_cameraManager.CameraView.ViewfinderMode)
{
_previewRect.Width = _cameraManager.PreviewLayer.Bounds.Width;
_previewRect.Height = _cameraManager.PreviewLayer.Bounds.Height;
Expand All @@ -103,7 +105,7 @@ public override void DidOutputSampleBuffer(AVCaptureOutput captureOutput, CMSamp
}
}

_cameraManager?.CameraView?.DetectionFinished(_barcodeResults, _resultsLock);
_cameraManager.CameraView.DetectionFinished(_barcodeResults, _resultsLock);
}
catch (Exception ex)
{
Expand Down

0 comments on commit fca72c2

Please sign in to comment.