Skip to content

Commit

Permalink
Save and re-set iOS config on shutdown
Browse files Browse the repository at this point in the history
Apparently if you change some AVCaptureDevice settings on iOS and don't change them back, they are persisted to subsequent uses of the device within the same app.
  • Loading branch information
Redth committed Mar 13, 2020
1 parent 571b132 commit 2195a09
Showing 1 changed file with 89 additions and 33 deletions.
122 changes: 89 additions & 33 deletions ZXing.Net.Mobile/iOS/ZXingScannerView.ios.cs
Expand Up @@ -37,6 +37,7 @@ public ZXingScannerView(CGRect frame) : base(frame)
}

AVCaptureSession session;
AVCaptureDevice captureDevice = null;
AVCaptureVideoPreviewLayer previewLayer;
AVCaptureVideoDataOutput output;
OutputRecorder outputRecorder;
Expand All @@ -56,7 +57,9 @@ public ZXingScannerView(CGRect frame) : base(frame)

bool shouldRotatePreviewBuffer = false;

void Setup(CGRect frame)
AVConfigs captureDeviceOriginalConfig;

void Setup()
{
var started = DateTime.UtcNow;

Expand Down Expand Up @@ -91,7 +94,6 @@ void Setup(CGRect frame)
bool torch = false;
bool analyzing = true;


bool SetupCaptureSession()
{
var started = DateTime.UtcNow;
Expand All @@ -114,8 +116,6 @@ bool SetupCaptureSession()
};

// create a device input and attach it to the session
// var captureDevice = AVCaptureDevice.DefaultDeviceWithMediaType (AVMediaType.Video);
AVCaptureDevice captureDevice = null;
var devices = AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video);
foreach (var device in devices)
{
Expand Down Expand Up @@ -273,9 +273,25 @@ bool SetupCaptureSession()

var perf5 = PerformanceCounter.Start();

NSError err = null;
if (captureDevice.LockForConfiguration(out err))
if (captureDevice.LockForConfiguration(out var err))
{
captureDeviceOriginalConfig = new AVConfigs
{
FocusMode = captureDevice.FocusMode,
ExposureMode = captureDevice.ExposureMode,
WhiteBalanceMode = captureDevice.WhiteBalanceMode,
AutoFocusRangeRestriction = captureDevice.AutoFocusRangeRestriction,
};

if (captureDevice.HasFlash)
captureDeviceOriginalConfig.FlashMode = captureDevice.FlashMode;
if (captureDevice.HasTorch)
captureDeviceOriginalConfig.TorchMode = captureDevice.TorchMode;
if (captureDevice.FocusPointOfInterestSupported)
captureDeviceOriginalConfig.FocusPointOfInterest = captureDevice.FocusPointOfInterest;
if (captureDevice.ExposurePointOfInterestSupported)
captureDeviceOriginalConfig.ExposurePointOfInterest = captureDevice.ExposurePointOfInterest;

if (ScanningOptions.DisableAutofocus)
{
captureDevice.FocusMode = AVCaptureFocusMode.Locked;
Expand All @@ -299,7 +315,9 @@ bool SetupCaptureSession()
captureDevice.WhiteBalanceMode = AVCaptureWhiteBalanceMode.AutoWhiteBalance;

if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0) && captureDevice.AutoFocusRangeRestrictionSupported)
{
captureDevice.AutoFocusRangeRestriction = AVCaptureAutoFocusRangeRestriction.Near;
}

if (captureDevice.FocusPointOfInterestSupported)
captureDevice.FocusPointOfInterest = new PointF(0.5f, 0.5f);
Expand Down Expand Up @@ -489,7 +507,7 @@ public void StartScanning(Action<Result> scanResultHandler, MobileBarcodeScannin

var perf = PerformanceCounter.Start();

Setup(Frame);
Setup();

ScanningOptions = options ?? MobileBarcodeScanningOptions.Default;
resultCallback = scanResultHandler;
Expand All @@ -506,10 +524,11 @@ public void StartScanning(Action<Result> scanResultHandler, MobileBarcodeScannin
if (Runtime.Arch == Arch.SIMULATOR)
{
var simView = new UIView(new CGRect(0, 0, this.Frame.Width, this.Frame.Height));
simView.BackgroundColor = UIColor.LightGray;
simView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
InsertSubview(simView, 0);
InsertSubview(new UIView(new CGRect(0, 0, this.Frame.Width, this.Frame.Height))
{
BackgroundColor = UIColor.LightGray,
AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
}, 0);
}
});
Expand Down Expand Up @@ -540,6 +559,30 @@ public void StopScanning()
if (outputRecorder != null)
outputRecorder.CancelTokenSource.Cancel();

// Revert camera settings to original
if (captureDevice != null && captureDevice.LockForConfiguration(out var err))
{
captureDevice.FocusMode = captureDeviceOriginalConfig.FocusMode;
captureDevice.ExposureMode = captureDeviceOriginalConfig.ExposureMode;
captureDevice.WhiteBalanceMode = captureDeviceOriginalConfig.WhiteBalanceMode;

if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0) && captureDevice.AutoFocusRangeRestrictionSupported)
captureDevice.AutoFocusRangeRestriction = captureDeviceOriginalConfig.AutoFocusRangeRestriction;

if (captureDevice.FocusPointOfInterestSupported)
captureDevice.FocusPointOfInterest = captureDeviceOriginalConfig.FocusPointOfInterest;

if (captureDevice.ExposurePointOfInterestSupported)
captureDevice.ExposurePointOfInterest = captureDeviceOriginalConfig.ExposurePointOfInterest;

if (captureDevice.HasFlash)
captureDevice.FlashMode = captureDeviceOriginalConfig.FlashMode;
if (captureDevice.HasTorch)
captureDevice.TorchMode = captureDeviceOriginalConfig.TorchMode;

captureDevice.UnlockForConfiguration();
}

//Try removing all existing outputs prior to closing the session
try
{
Expand Down Expand Up @@ -572,34 +615,35 @@ public void Torch(bool on)
{
try
{
NSError err;

var device = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);

if (device.HasTorch || device.HasFlash)
var device = captureDevice ?? AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
if (device != null && (device.HasTorch || device.HasFlash))
{
device.LockForConfiguration(out var err);

device.LockForConfiguration(out err);

if (on)
if (err != null)
{
if (device.HasTorch)
device.TorchMode = AVCaptureTorchMode.On;
if (device.HasFlash)
device.FlashMode = AVCaptureFlashMode.On;
if (on)
{
if (device.HasTorch)
device.TorchMode = AVCaptureTorchMode.On;
if (device.HasFlash)
device.FlashMode = AVCaptureFlashMode.On;
}
else
{
if (device.HasTorch)
device.TorchMode = AVCaptureTorchMode.Off;
if (device.HasFlash)
device.FlashMode = AVCaptureFlashMode.Off;
}
}
else

try
{
if (device.HasTorch)
device.TorchMode = AVCaptureTorchMode.Off;
if (device.HasFlash)
device.FlashMode = AVCaptureFlashMode.Off;
device.UnlockForConfiguration();
}

device.UnlockForConfiguration();
catch { }
}
device = null;


torch = on;
}
Expand Down Expand Up @@ -636,11 +680,23 @@ public bool HasTorch
if (hasTorch.HasValue)
return hasTorch.Value;

var device = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
var device = captureDevice ?? AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
hasTorch = device.HasFlash || device.HasTorch;
return hasTorch.Value;
}
}
#endregion
}

struct AVConfigs
{
public AVCaptureFocusMode FocusMode;
public AVCaptureExposureMode ExposureMode;
public AVCaptureWhiteBalanceMode WhiteBalanceMode;
public AVCaptureAutoFocusRangeRestriction AutoFocusRangeRestriction;
public CGPoint FocusPointOfInterest;
public CGPoint ExposurePointOfInterest;
public AVCaptureFlashMode FlashMode;
public AVCaptureTorchMode TorchMode;
}
}

0 comments on commit 2195a09

Please sign in to comment.