Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<Picker
Title="Cameras"
ItemsSource="{Binding Cameras}"
ItemDisplayBinding="{Binding Name}"
ItemDisplayBinding="{Binding SelectedCamera.Name}"
SelectedItem="{Binding SelectedCamera}" />

<Picker
Expand Down
48 changes: 24 additions & 24 deletions src/CommunityToolkit.Maui.Camera/CameraManager.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ public async partial ValueTask UpdateCaptureResolution(Size resolution, Cancella

resolutionSelector?.Dispose();

resolutionSelector = new ResolutionSelector.Builder()
.SetAllowedResolutionMode(ResolutionSelector.PreferHigherResolutionOverCaptureRate)
.SetResolutionFilter(resolutionFilter)
resolutionSelector = new ResolutionSelector.Builder()?
.SetAllowedResolutionMode(ResolutionSelector.PreferHigherResolutionOverCaptureRate)?
.SetResolutionFilter(resolutionFilter)?
.Build();

if (IsInitialized)
Expand Down Expand Up @@ -229,23 +229,23 @@ protected async Task StartUseCase(CancellationToken token)
videoCapture?.Dispose();
videoRecorder?.Dispose();

cameraPreview = new Preview.Builder().SetResolutionSelector(resolutionSelector).Build();
cameraPreview.SetSurfaceProvider(cameraExecutor, previewView?.SurfaceProvider);
cameraPreview = new Preview.Builder().SetResolutionSelector(resolutionSelector)?.Build();
cameraPreview?.SetSurfaceProvider(cameraExecutor, previewView?.SurfaceProvider);

imageCapture = new ImageCapture.Builder()
.SetCaptureMode(ImageCapture.CaptureModeMaximizeQuality)
.SetResolutionSelector(resolutionSelector)
imageCapture = new ImageCapture.Builder()?
.SetCaptureMode(ImageCapture.CaptureModeMaximizeQuality)?
.SetResolutionSelector(resolutionSelector)?
.Build();

var videoRecorderBuilder = new Recorder.Builder()
.SetExecutor(cameraExecutor);

if (Quality.Highest is not null)
{
videoRecorderBuilder = videoRecorderBuilder.SetQualitySelector(QualitySelector.From(Quality.Highest));
videoRecorderBuilder = videoRecorderBuilder?.SetQualitySelector(QualitySelector.From(Quality.Highest));
}

videoRecorder = videoRecorderBuilder.Build();
videoRecorder = videoRecorderBuilder?.Build();
videoCapture = VideoCapture.WithOutput(videoRecorder);

await StartCameraPreview(token);
Expand All @@ -271,9 +271,9 @@ protected virtual async partial Task PlatformStartCameraPreview(CancellationToke
camera = await RebindCamera(processCameraProvider, cameraView.SelectedCamera, token, cameraPreview, imageCapture, videoCapture);
cameraControl = camera.CameraControl;

var point = previewView.MeteringPointFactory.CreatePoint(previewView.Width / 2.0f, previewView.Height / 2.0f, 0.1f);
var point = previewView.MeteringPointFactory?.CreatePoint(previewView.Width / 2.0f, previewView.Height / 2.0f, 0.1f);
var action = new FocusMeteringAction.Builder(point).Build();
camera.CameraControl.StartFocusAndMetering(action);
camera.CameraControl?.StartFocusAndMetering(action);

IsInitialized = true;
OnLoaded.Invoke();
Expand Down Expand Up @@ -342,8 +342,8 @@ protected virtual async partial Task PlatformStartVideoRecording(Stream stream,
videoRecordingFinalizeTcs = new TaskCompletionSource();
var captureListener = new CameraConsumer(videoRecordingFinalizeTcs);
var executor = ContextCompat.GetMainExecutor(context) ?? throw new CameraException($"Unable to retrieve {nameof(IExecutorService)}");
videoRecording = videoRecorder
.PrepareRecording(context, outputOptions)
videoRecording = videoRecorder?
.PrepareRecording(context, outputOptions)?
.WithAudioEnabled()
.Start(executor, captureListener);
}
Expand Down Expand Up @@ -416,7 +416,7 @@ async Task<CameraSelector> EnableModes(CameraInfo selectedCamera, CancellationTo
}

var extensionsManagerFuture = ExtensionsManager.GetInstanceAsync(context, cameraProviderInstance);
extensionsManagerFuture.AddListener(new Runnable(() =>
extensionsManagerFuture?.AddListener(new Runnable(() =>
{
var extensionsManager = (ExtensionsManager?)extensionsManagerFuture.Get();
if (extensionsManager is not null && extensionsManager.IsExtensionAvailable(cameraSelector, extensionMode))
Expand Down Expand Up @@ -455,10 +455,10 @@ void SetImageCaptureTargetRotation(int rotation)

sealed class ImageCallBack(ICameraView cameraView) : ImageCapture.OnImageCapturedCallback
{
public override void OnCaptureSuccess(IImageProxy image)
public override void OnCaptureSuccess(IImageProxy? image)
{
base.OnCaptureSuccess(image);
var img = image.Image;
var img = image?.Image;

if (img is null)
{
Expand All @@ -471,7 +471,7 @@ public override void OnCaptureSuccess(IImageProxy image)
if (buffer is null)
{
cameraView.OnMediaCapturedFailed("Unable to obtain a buffer for the image plane.");
image.Close();
image?.Close();
return;
}

Expand All @@ -489,7 +489,7 @@ public override void OnCaptureSuccess(IImageProxy image)
}
finally
{
image.Close();
image?.Close();
}

static Image.Plane? GetFirstPlane(Image.Plane[]? planes)
Expand All @@ -503,24 +503,24 @@ public override void OnCaptureSuccess(IImageProxy image)
}
}

public override void OnError(ImageCaptureException exception)
public override void OnError(ImageCaptureException? exception)
{
base.OnError(exception);
cameraView.OnMediaCapturedFailed(exception.Message ?? "An unknown error occurred.");
cameraView.OnMediaCapturedFailed(exception?.Message ?? "An unknown error occurred.");
}
}

sealed class ResolutionFilter(Android.Util.Size size) : Object, IResolutionFilter
{
public Android.Util.Size TargetSize { get; set; } = size;

public IList<Android.Util.Size> Filter(IList<Android.Util.Size> supportedSizes, int rotationDegrees)
public IList<Android.Util.Size> Filter(IList<Android.Util.Size>? supportedSizes, int rotationDegrees)
{
var filteredList = supportedSizes
var filteredList = supportedSizes?
.Where(size => size.Width <= TargetSize.Width && size.Height <= TargetSize.Height)
.OrderByDescending(size => size.Width * size.Height).ToList();

return filteredList.Count is 0 ? supportedSizes : filteredList;
return filteredList?.Count is 0 ? supportedSizes ?? [] : filteredList ?? [];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@

<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">
<!-- Required NuGet Packages -->
<PackageReference Include="Xamarin.AndroidX.Camera.Camera2" Version="1.4.2.2" />
<PackageReference Include="Xamarin.AndroidX.Camera.View" Version="1.4.2.2" />
<PackageReference Include="Xamarin.AndroidX.Camera.Extensions" Version="1.4.2.2" />
<PackageReference Include="Xamarin.AndroidX.Camera.Camera2" Version="1.5.0" />
<PackageReference Include="Xamarin.AndroidX.Camera.View" Version="1.5.0" />
<PackageReference Include="Xamarin.AndroidX.Camera.Extensions" Version="1.5.0" />

<PackageReference Include="Xamarin.AndroidX.Activity.Ktx" Version="1.11.0" />

<!-- Ensure Linker does not remove required libraries -->
<None Include="linker.xml" Pack="true" PackagePath="build\$(PackageId).LinkerConfigurationFile.xml" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public async partial ValueTask RefreshAvailableCameras(CancellationToken token)

if (CameraCharacteristics.ScalerStreamConfigurationMap is not null)
{
var streamConfigMap = camera2Info.GetCameraCharacteristic(CameraCharacteristics.ScalerStreamConfigurationMap) as StreamConfigurationMap;
var streamConfigMap = camera2Info?.GetCameraCharacteristic(CameraCharacteristics.ScalerStreamConfigurationMap) as StreamConfigurationMap;

if (OperatingSystem.IsAndroidVersionAtLeast(23))
{
Expand All @@ -68,13 +68,13 @@ public async partial ValueTask RefreshAvailableCameras(CancellationToken token)
}

var cameraInfo = new CameraInfo(name,
camera2Info.CameraId,
camera2Info?.CameraId ?? string.Empty,
position,
cameraXInfo.HasFlashUnit,
(cameraXInfo.ZoomState.Value as IZoomState)?.MinZoomRatio ?? 1.0f,
(cameraXInfo.ZoomState.Value as IZoomState)?.MaxZoomRatio ?? 1.0f,
(cameraXInfo.ZoomState?.Value as IZoomState)?.MinZoomRatio ?? 1.0f,
(cameraXInfo.ZoomState?.Value as IZoomState)?.MaxZoomRatio ?? 1.0f,
supportedResolutions,
cameraXInfo.CameraSelector);
cameraXInfo?.CameraSelector ?? throw new InvalidOperationException("CameraSelector cannot be null"));

availableCameras.Add(cameraInfo);
}
Expand Down
Loading