Skip to content

Commit

Permalink
Fixes to ZXing[Texture|Surface]View after merge of PR #533
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsenko committed May 31, 2017
1 parent 6ce1729 commit 7d60a20
Show file tree
Hide file tree
Showing 14 changed files with 842 additions and 958 deletions.
2 changes: 1 addition & 1 deletion Samples/Forms/Core/CustomScanPage.cs
Expand Up @@ -28,7 +28,7 @@ public CustomScanPage () : base ()
formats.Add(ZXing.BarcodeFormat.CODE_39);
formats.Add(ZXing.BarcodeFormat.QR_CODE);

zxing.Options.DelayBetweenContinuousScans = 1000; // same barcode can only be scanned once a second. Different barcodes is a different matter
zxing.Options.DelayBetweenContinuousScans = 1000;

zxing.IsTorchOn = true;

Expand Down
2 changes: 1 addition & 1 deletion Samples/Forms/Droid/FormsSample.Droid.csproj
Expand Up @@ -16,7 +16,7 @@
<AssemblyName>FormsSample.Droid</AssemblyName>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
<TargetFrameworkVersion>v7.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
Expand Down
8 changes: 0 additions & 8 deletions Samples/Forms/iOS/FormsSample.iOS.csproj
Expand Up @@ -23,8 +23,6 @@
<ConsolePause>false</ConsolePause>
<MtouchArch>i386</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchUseRefCounting>true</MtouchUseRefCounting>
<MtouchUseSGen>true</MtouchUseSGen>
<MtouchFastDev>true</MtouchFastDev>
<MtouchDebug>true</MtouchDebug>
<CodesignKey>iPhone Developer</CodesignKey>
Expand All @@ -40,9 +38,7 @@
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchFloat32>true</MtouchFloat32>
<MtouchUseSGen>true</MtouchUseSGen>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchUseRefCounting>true</MtouchUseRefCounting>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>full</DebugType>
Expand All @@ -53,9 +49,7 @@
<ConsolePause>false</ConsolePause>
<MtouchArch>i386</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchUseRefCounting>true</MtouchUseRefCounting>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchUseSGen>true</MtouchUseSGen>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
Expand All @@ -72,8 +66,6 @@
<CodesignKey>iPhone Developer</CodesignKey>
<DeviceSpecificBuild>true</DeviceSpecificBuild>
<MtouchDebug>true</MtouchDebug>
<MtouchUseSGen>true</MtouchUseSGen>
<MtouchUseRefCounting>true</MtouchUseRefCounting>
<MtouchProfiling>true</MtouchProfiling>
</PropertyGroup>
<ItemGroup>
Expand Down
70 changes: 29 additions & 41 deletions Source/ZXing.Net.Mobile.Android/CameraAccess/CameraAnalyzer.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Android.Views;
using ApxLabs.FastAndroidCamera;

namespace ZXing.Mobile.CameraAccess
Expand All @@ -10,18 +9,16 @@ public class CameraAnalyzer
{
private readonly CameraController _cameraController;
private readonly MobileBarcodeScanningOptions _scanningOptions;
private readonly CameraEventsListener _cameraEventListener;
private Task _processingTask;
private DateTime _lastPreviewAnalysis = DateTime.UtcNow;
private bool _wasScanned;
private BarcodeReaderGeneric<FastJavaByteArrayYUVLuminanceSource> _barcodeReader;

public CameraAnalyzer(SurfaceView surfaceView, MobileBarcodeScanningOptions scanningOptions)
public CameraAnalyzer(CameraController cameraController, MobileBarcodeScanningOptions scanningOptions)
{
_scanningOptions = scanningOptions;
_cameraEventListener = new CameraEventsListener();
_cameraController = new CameraController(surfaceView, _cameraEventListener, scanningOptions);
Torch = new Torch(_cameraController, surfaceView.Context);
_cameraController = cameraController;

Torch = new Torch(_cameraController);
}

public event EventHandler<Result> BarcodeFound;
Expand All @@ -43,13 +40,13 @@ public void ResumeAnalysis()
public void ShutdownCamera()
{
IsAnalyzing = false;
_cameraEventListener.OnPreviewFrameReady -= HandleOnPreviewFrameReady;
_cameraController.OnPreviewFrameReady -= HandleOnPreviewFrameReady;
_cameraController.ShutdownCamera();
}

public void SetupCamera()
{
_cameraEventListener.OnPreviewFrameReady += HandleOnPreviewFrameReady;
_cameraController.OnPreviewFrameReady += HandleOnPreviewFrameReady;
_cameraController.SetupCamera();
}

Expand All @@ -75,11 +72,6 @@ private bool CanAnalyzeFrame
if (!IsAnalyzing)
return false;

//Check and see if we're still processing a previous frame
// todo: check if we can run as many as possible or mby run two analyzers at once (Vision + ZXing)
if (_processingTask != null && !_processingTask.IsCompleted)
return false;

var elapsedTimeMs = (DateTime.UtcNow - _lastPreviewAnalysis).TotalMilliseconds;
if (elapsedTimeMs < _scanningOptions.DelayBetweenAnalyzingFrames)
return false;
Expand All @@ -100,19 +92,14 @@ private void HandleOnPreviewFrameReady(object sender, FastJavaByteArray fastArra
_wasScanned = false;
_lastPreviewAnalysis = DateTime.UtcNow;

_processingTask = Task.Run(() =>
{
try
{
DecodeFrame(fastArray);
} catch (Exception ex) {
Console.WriteLine(ex);
}
}).ContinueWith(task =>
try
{
DecodeFrame(fastArray);
}
catch (Exception ex)
{
if (task.IsFaulted)
Android.Util.Log.Debug(MobileBarcodeScanner.TAG, "DecodeFrame exception occurs");
}, TaskContinuationOptions.OnlyOnFaulted);
Android.Util.Log.Debug(MobileBarcodeScanner.TAG, $"DecodeFrame exception occured: {ex.Message}");
}
}

private byte[] buffer;
Expand All @@ -131,28 +118,29 @@ private void DecodeFrame(FastJavaByteArray fastArray)
Result result = null;
var start = PerformanceCounter.Start();

if (rotate)
fastArray.RotateInPlace(ref buffer, width, height);
if (rotate)
{
fastArray.Transpose(ref buffer, width, height);
var tmp = width;
width = height;
height = tmp;
}

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

result = _barcodeReader.Decode(luminanceSource);

fastArray.Dispose();
fastArray = null;

PerformanceCounter.Stop(start,
"Decode Time: {0} ms (width: " + width + ", height: " + height + ", degrees: " + cDegrees + ", rotate: " +
rotate + ")");
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);
if (result != null)
{
Android.Util.Log.Debug(MobileBarcodeScanner.TAG, "Barcode Found: " + result.Text);

_wasScanned = true;
BarcodeFound?.Invoke(this, result);
return;
}
_wasScanned = true;
BarcodeFound?.Invoke(this, result);
}
else
AutoFocus();
}

private void InitBarcodeReaderIfNeeded()
Expand Down
72 changes: 36 additions & 36 deletions Source/ZXing.Net.Mobile.Android/CameraAccess/CameraController.cs
Expand Up @@ -17,22 +17,35 @@ public class CameraController
private readonly Context _context;
private readonly MobileBarcodeScanningOptions _scanningOptions;
private readonly ISurfaceHolder _holder;
private readonly SurfaceView _surfaceView;
private readonly CameraEventsListener _cameraEventListener;
private int _cameraId;
private bool _autoFocusCycleDone = true;
private bool _useContinousFocus;

public CameraController(SurfaceView surfaceView, CameraEventsListener cameraEventListener,
MobileBarcodeScanningOptions scanningOptions)
{
SurfaceView = surfaceView;

_context = surfaceView.Context;
_scanningOptions = scanningOptions;
_holder = surfaceView.Holder;
_surfaceView = surfaceView;

_cameraEventListener = cameraEventListener;
_scanningOptions = scanningOptions;
_cameraEventListener.AutoFocus += (s, e) =>
_autoFocusCycleDone = true;
}

public SurfaceView SurfaceView { get; }

public Camera Camera { get; private set; }

public event EventHandler<FastJavaByteArray> OnPreviewFrameReady
{
add { _cameraEventListener.OnPreviewFrameReady += value; }
remove { _cameraEventListener.OnPreviewFrameReady -= value; }
}

public int LastCameraDisplayOrientationDegree { get; private set; }

public void RefreshCamera()
Expand Down Expand Up @@ -78,13 +91,8 @@ public void SetupCamera()


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);
}

using (var buffer = new FastJavaByteArray(bufferSize))
Camera.AddCallbackBuffer(buffer);


Camera.StartPreview();
Expand Down Expand Up @@ -117,8 +125,8 @@ public void AutoFocus(int x, int y)
{
// The bounds for focus areas are actually -1000 to 1000
// So we need to translate the touch coordinates to this scale
var focusX = x / _surfaceView.Width * 2000 - 1000;
var focusY = y / _surfaceView.Height * 2000 - 1000;
var focusX = x / SurfaceView.Width * 2000 - 1000;
var focusY = y / SurfaceView.Height * 2000 - 1000;

// Call the autofocus with our coords
AutoFocus(focusX, focusY, true);
Expand All @@ -134,10 +142,9 @@ public void ShutdownCamera()
{
try
{
//Camera.SetPreviewCallback(null);
Camera.SetPreviewDisplay(null);
Camera.StopPreview();
Camera.SetNonMarshalingPreviewCallback(null);
Camera.SetNonMarshalingPreviewCallback(null); // replaces Camera.SetPreviewCallback(null);
}
catch (Exception ex)
{
Expand Down Expand Up @@ -201,11 +208,6 @@ private void OpenCamera()
{
Camera = Camera.Open();
}

//if (Camera != null)
// Camera.SetPreviewCallback(_cameraEventListener);
//else
// MobileBarcodeScanner.LogWarn(MobileBarcodeScanner.TAG, "Camera is null :(");
}
catch (Exception ex)
{
Expand All @@ -217,8 +219,13 @@ private void OpenCamera()
private void ApplyCameraSettings()
{
var parameters = Camera.GetParameters();
parameters.PreviewFormat = ImageFormatType.Nv21;
parameters.PreviewFormat = ImageFormatType.Nv21; // YCrCb format (all Android devices must support this)

// Android actually defines a barcode scene mode ..
if (parameters.SupportedSceneModes.Contains(Camera.Parameters.SceneModeBarcode)) // .. we might be lucky :-)
parameters.SceneMode = Camera.Parameters.SceneModeBarcode;

// First try continuous video, then auto focus, then fixed
var supportedFocusModes = parameters.SupportedFocusModes;
if (Build.VERSION.SdkInt >= BuildVersionCodes.IceCreamSandwich &&
supportedFocusModes.Contains(Camera.Parameters.FocusModeContinuousPicture))
Expand All @@ -230,20 +237,6 @@ private void ApplyCameraSettings()
else if (supportedFocusModes.Contains(Camera.Parameters.FocusModeFixed))
parameters.FocusMode = Camera.Parameters.FocusModeFixed;

var selectedFps = parameters.SupportedPreviewFpsRange.FirstOrDefault();
if (selectedFps != null)
{
// This will make sure we select a range with the lowest minimum FPS
// and maximum FPS which still has the lowest minimum
// This should help maximize performance / support for hardware
foreach (var fpsRange in parameters.SupportedPreviewFpsRange)
{
if (fpsRange[0] <= selectedFps[0] && fpsRange[1] > selectedFps[1])
selectedFps = fpsRange;
}
parameters.SetPreviewFpsRange(selectedFps[0], selectedFps[1]);
}

var availableResolutions = parameters.SupportedPreviewSizes.Select(sps => new CameraResolution
{
Width = sps.Width,
Expand Down Expand Up @@ -292,12 +285,18 @@ private void ApplyCameraSettings()

Camera.SetParameters(parameters);

parameters = Camera.GetParameters(); // refresh to see what is actually set!

_useContinousFocus = parameters.FocusMode == Camera.Parameters.FocusModeContinuousPicture || parameters.FocusMode == Camera.Parameters.FocusModeContinuousVideo;

SetCameraDisplayOrientation();
}

private void AutoFocus(int x, int y, bool useCoordinates)
{
if (Camera == null) return;
if (_useContinousFocus || !_autoFocusCycleDone || Camera == null)
return;

var cameraParams = Camera.GetParameters();

Android.Util.Log.Debug(MobileBarcodeScanner.TAG, "AutoFocus Requested");
Expand All @@ -317,7 +316,7 @@ private void AutoFocus(int x, int y, bool useCoordinates)
// So we'll offset -10 from the center of the touch and then
// make a rect of 20 to give an area to focus on based on the center of the touch
x = x - 10;
y = y - 10;
y = y - 10; // todo: ensure positive!

// Ensure we don't go over the -1000 to 1000 limit of focus area
if (x >= 1000)
Expand All @@ -340,6 +339,7 @@ private void AutoFocus(int x, int y, bool useCoordinates)
}

// Finally autofocus (weather we used focus areas or not)
_autoFocusCycleDone = false;
Camera.AutoFocus(_cameraEventListener);
}
catch (Exception ex)
Expand Down

0 comments on commit 7d60a20

Please sign in to comment.