diff --git a/BigIslandBarcode/MainPage.xaml b/BigIslandBarcode/MainPage.xaml
index 7ef9b2b..42691f8 100644
--- a/BigIslandBarcode/MainPage.xaml
+++ b/BigIslandBarcode/MainPage.xaml
@@ -11,13 +11,15 @@
x:Name="barcodeView"
BarcodesDetected="BarcodesDetected"
/>
-
-
+
+
+
-
+
-
- SetValue(SelectedCameraProperty, value);
}
+ public static readonly BindableProperty ZoomFactorProperty =
+ BindableProperty.Create(nameof(ZoomFactor), typeof(float), typeof(CameraBarcodeReaderView), defaultValue: 0f);
+
+ public float ZoomFactor
+ {
+ get => (float)GetValue(ZoomFactorProperty);
+ set => SetValue(ZoomFactorProperty, value);
+ }
+
public void AutoFocus()
=> StrongHandler?.Invoke(nameof(AutoFocus), null);
diff --git a/ZXing.Net.MAUI.Controls/Controls/CameraView.cs b/ZXing.Net.MAUI.Controls/Controls/CameraView.cs
index d8d7918..5f1bb82 100644
--- a/ZXing.Net.MAUI.Controls/Controls/CameraView.cs
+++ b/ZXing.Net.MAUI.Controls/Controls/CameraView.cs
@@ -40,6 +40,15 @@ public CameraInfo SelectedCamera
set => SetValue(SelectedCameraProperty, value);
}
+ public static readonly BindableProperty ZoomFactorProperty =
+ BindableProperty.Create(nameof(ZoomFactor), typeof(float), typeof(CameraView), defaultValue: 0f);
+
+ public float ZoomFactor
+ {
+ get => (float)GetValue(ZoomFactorProperty);
+ set => SetValue(ZoomFactorProperty, value);
+ }
+
public void AutoFocus()
=> StrongHandler?.Invoke(nameof(AutoFocus), null);
diff --git a/ZXing.Net.MAUI/Apple/CameraManager.ios.maccatalyst.cs b/ZXing.Net.MAUI/Apple/CameraManager.ios.maccatalyst.cs
index 3163ebf..0086bc6 100644
--- a/ZXing.Net.MAUI/Apple/CameraManager.ios.maccatalyst.cs
+++ b/ZXing.Net.MAUI/Apple/CameraManager.ios.maccatalyst.cs
@@ -199,6 +199,7 @@ public void UpdateCamera()
captureSession.AddInput(captureInput);
captureSession.StartRunning();
+
}
}
@@ -269,6 +270,27 @@ public void UpdateTorch(bool on)
}
}
+ partial void ApplyZoomFactor()
+ {
+ if (captureDevice == null)
+ return;
+
+ var minZoomFactor = 1f;
+ // Cap zoom to the max optical range (higher values can engage digital zoom and degrade clarity).
+ var maxZoomFactor = Math.Min((float)captureDevice.ActiveFormat.VideoMaxZoomFactor, 5.0f);
+ if (maxZoomFactor < minZoomFactor)
+ maxZoomFactor = minZoomFactor;
+
+ var normalizedZoomFactor = ZoomFactor * (maxZoomFactor - minZoomFactor) + minZoomFactor;
+ if (normalizedZoomFactor < minZoomFactor)
+ normalizedZoomFactor = minZoomFactor;
+ else if (normalizedZoomFactor > maxZoomFactor)
+ normalizedZoomFactor = maxZoomFactor;
+
+ CaptureDevicePerformWithLockedConfiguration(() =>
+ captureDevice.VideoZoomFactor = normalizedZoomFactor);
+ }
+
public void Focus(Microsoft.Maui.Graphics.Point point)
{
if (captureDevice == null)
diff --git a/ZXing.Net.MAUI/CameraBarcodeReaderViewHandler.cs b/ZXing.Net.MAUI/CameraBarcodeReaderViewHandler.cs
index 56c18cf..182efdc 100644
--- a/ZXing.Net.MAUI/CameraBarcodeReaderViewHandler.cs
+++ b/ZXing.Net.MAUI/CameraBarcodeReaderViewHandler.cs
@@ -19,6 +19,7 @@ public partial class CameraBarcodeReaderViewHandler : ViewHandler handler.cameraManager?.UpdateTorch(virtualView.IsTorchOn),
[nameof(ICameraBarcodeReaderView.CameraLocation)] = (handler, virtualView) => handler.cameraManager?.UpdateCameraLocation(virtualView.CameraLocation),
[nameof(ICameraBarcodeReaderView.SelectedCamera)] = (handler, virtualView) => handler.cameraManager?.UpdateSelectedCamera(virtualView.SelectedCamera),
+ [nameof(ICameraBarcodeReaderView.ZoomFactor)] = (handler, virtualView) => handler.cameraManager?.UpdateZoomFactor(virtualView.ZoomFactor),
[nameof(IView.Visibility)] = MapVisibility
};
diff --git a/ZXing.Net.MAUI/CameraManager.cs b/ZXing.Net.MAUI/CameraManager.cs
index 53068bb..bae2313 100644
--- a/ZXing.Net.MAUI/CameraManager.cs
+++ b/ZXing.Net.MAUI/CameraManager.cs
@@ -22,6 +22,7 @@ public CameraManager(IMauiContext context, CameraLocation cameraLocation)
public CameraLocation CameraLocation { get; private set; }
public CameraInfo SelectedCamera { get; private set; }
+ public float ZoomFactor { get; private set; }
///
/// Gets a value indicating whether barcode scanning is supported on this device.
@@ -48,7 +49,15 @@ public void UpdateSelectedCamera(CameraInfo cameraInfo)
UpdateCamera();
}
+ public void UpdateZoomFactor(float zoomFactor)
+ {
+ ZoomFactor = Math.Clamp(zoomFactor, 0f, 1f);
+ ApplyZoomFactor();
+ }
+
public static async Task CheckPermissions()
=> (await Permissions.RequestAsync()) == PermissionStatus.Granted;
+
+ partial void ApplyZoomFactor();
}
}
diff --git a/ZXing.Net.MAUI/CameraViewHandler.cs b/ZXing.Net.MAUI/CameraViewHandler.cs
index b22b23a..d361a1a 100644
--- a/ZXing.Net.MAUI/CameraViewHandler.cs
+++ b/ZXing.Net.MAUI/CameraViewHandler.cs
@@ -15,6 +15,7 @@ public partial class CameraViewHandler : ViewHandler handler.cameraManager?.UpdateTorch(virtualView.IsTorchOn),
[nameof(ICameraView.CameraLocation)] = (handler, virtualView) => handler.cameraManager?.UpdateCameraLocation(virtualView.CameraLocation),
[nameof(ICameraView.SelectedCamera)] = (handler, virtualView) => handler.cameraManager?.UpdateSelectedCamera(virtualView.SelectedCamera),
+ [nameof(ICameraView.ZoomFactor)] = (handler, virtualView) => handler.cameraManager?.UpdateZoomFactor(virtualView.ZoomFactor),
[nameof(IView.Visibility)] = MapVisibility
};
diff --git a/ZXing.Net.MAUI/ICameraView.cs b/ZXing.Net.MAUI/ICameraView.cs
index c79b79d..441c7b9 100644
--- a/ZXing.Net.MAUI/ICameraView.cs
+++ b/ZXing.Net.MAUI/ICameraView.cs
@@ -14,6 +14,8 @@ public interface ICameraView : IView, ICameraFrameAnalyzer
CameraInfo SelectedCamera { get; set; }
+ float ZoomFactor { get; set; }
+
//CameraMode Mode { get; set; }
void AutoFocus();
diff --git a/ZXing.Net.MAUI/Net/CameraManager.net.cs b/ZXing.Net.MAUI/Net/CameraManager.net.cs
index 89c5d70..9c7b42e 100644
--- a/ZXing.Net.MAUI/Net/CameraManager.net.cs
+++ b/ZXing.Net.MAUI/Net/CameraManager.net.cs
@@ -34,6 +34,10 @@ public void UpdateCamera()
public void UpdateTorch(bool on)
=> LogUnsupported();
+ partial void ApplyZoomFactor()
+ {
+ }
+
public void Focus(Microsoft.Maui.Graphics.Point point)
=> LogUnsupported();
diff --git a/ZXing.Net.MAUI/Platforms/Android/CameraManager.android.cs b/ZXing.Net.MAUI/Platforms/Android/CameraManager.android.cs
index df87af6..4ee58de 100644
--- a/ZXing.Net.MAUI/Platforms/Android/CameraManager.android.cs
+++ b/ZXing.Net.MAUI/Platforms/Android/CameraManager.android.cs
@@ -170,6 +170,8 @@ public void UpdateCamera()
// if not, this should be sufficient as a fallback
_camera = _cameraProvider.BindToLifecycle(maLifecycleOwner, _cameraSelector, _cameraPreview, _imageAnalyzer);
}
+
+ ApplyZoomFactor();
}
}
@@ -223,6 +225,11 @@ public void UpdateTorch(bool on)
_camera?.CameraControl?.EnableTorch(on);
}
+ partial void ApplyZoomFactor()
+ {
+ _camera?.CameraControl?.SetLinearZoom(ZoomFactor);
+ }
+
public void Focus(Point point)
{
diff --git a/ZXing.Net.MAUI/Platforms/Windows/CameraManager.windows.cs b/ZXing.Net.MAUI/Platforms/Windows/CameraManager.windows.cs
index ff3057c..a11a8df 100644
--- a/ZXing.Net.MAUI/Platforms/Windows/CameraManager.windows.cs
+++ b/ZXing.Net.MAUI/Platforms/Windows/CameraManager.windows.cs
@@ -209,6 +209,11 @@ public NativePlatformCameraPreviewView CreateNativeView()
public void UpdateTorch(bool on) => TryEnqueueUI(async () => await UpdateTorchAsync(on));
+ partial void ApplyZoomFactor()
+ {
+ TryEnqueueUI(async () => await ApplyZoomFactorAsync());
+ }
+
public void Focus(Microsoft.Maui.Graphics.Point point) => TryEnqueueUI(async () => await FocusAsync(point));
public void AutoFocus() => TryEnqueueUI(async () => await AutoFocusAsync());
@@ -633,6 +638,42 @@ private async Task UpdateTorchAsync(bool on)
}
}
+ private async Task ApplyZoomFactorAsync()
+ {
+ await MediaCaptureLifeLock.WaitAsync();
+
+ try
+ {
+ var zoomControl = _mediaCapture?.VideoDeviceController?.ZoomControl;
+ if (zoomControl?.Supported ?? false)
+ {
+ var minZoom = (float)zoomControl.Min;
+ var maxZoom = (float)zoomControl.Max;
+ if (maxZoom < minZoom)
+ maxZoom = minZoom;
+
+ var normalizedZoom = ZoomFactor * (maxZoom - minZoom) + minZoom;
+ if (normalizedZoom < minZoom)
+ normalizedZoom = minZoom;
+ else if (normalizedZoom > maxZoom)
+ normalizedZoom = maxZoom;
+
+ if (Math.Abs(zoomControl.Value - normalizedZoom) > float.Epsilon)
+ {
+ zoomControl.Value = normalizedZoom;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
+ }
+ finally
+ {
+ MediaCaptureLifeLock.Release();
+ }
+ }
+
private async Task FocusAsync(Microsoft.Maui.Graphics.Point point)
{
await MediaCaptureLifeLock.WaitAsync();