Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit 000acd0

Browse files
authored
Fixed camera preview size for Xiaomi Note 7 (#1780)
Further investigation required but the xiaomi has no "optimal sizes" for preview and is attempting to set the preview size to 4224x3136, which as a guess I would say is a raw resolution not accounting the dpi
1 parent ccf782c commit 000acd0

File tree

1 file changed

+107
-96
lines changed

1 file changed

+107
-96
lines changed

src/CommunityToolkit/Xamarin.CommunityToolkit/Views/CameraView/Android/CameraFragment.android.cs

Lines changed: 107 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -206,117 +206,118 @@ public async Task RetrieveCameraDevice(bool force = false)
206206

207207
// _texture.ClearCanvas(Element.BackgroundColor.ToAndroid()); // HANG after select valid camera...
208208
Element?.RaiseMediaCaptureFailed($"No {Element.CameraOptions} camera found");
209+
return;
209210
}
210-
else
211+
212+
try
211213
{
212-
try
213-
{
214-
var characteristics = Manager.GetCameraCharacteristics(cameraId);
215-
var map = (StreamConfigurationMap)(characteristics?.Get(CameraCharacteristics.ScalerStreamConfigurationMap) ?? throw new NullReferenceException());
214+
var characteristics = Manager.GetCameraCharacteristics(cameraId);
215+
var map = (StreamConfigurationMap)(characteristics?.Get(CameraCharacteristics.ScalerStreamConfigurationMap) ?? throw new NullReferenceException());
216216

217-
flashSupported = characteristics.Get(CameraCharacteristics.FlashInfoAvailable) == Java.Lang.Boolean.True;
218-
stabilizationSupported = false;
219-
var stabilizationModes = characteristics.Get(CameraCharacteristics.ControlAvailableVideoStabilizationModes);
217+
flashSupported = characteristics.Get(CameraCharacteristics.FlashInfoAvailable) == Java.Lang.Boolean.True;
218+
stabilizationSupported = false;
219+
var stabilizationModes = characteristics.Get(CameraCharacteristics.ControlAvailableVideoStabilizationModes);
220220

221-
if (stabilizationModes is IEnumerable<int> modes)
221+
if (stabilizationModes is IEnumerable<int> modes)
222+
{
223+
foreach (var mode in modes)
222224
{
223-
foreach (var mode in modes)
224-
{
225-
if (mode == (int)ControlVideoStabilizationMode.On)
226-
stabilizationSupported = true;
227-
}
225+
if (mode == (int)ControlVideoStabilizationMode.On)
226+
stabilizationSupported = true;
228227
}
228+
}
229229

230-
if (Element != null)
231-
Element.MaxZoom = maxDigitalZoom = (float)(characteristics.Get(CameraCharacteristics.ScalerAvailableMaxDigitalZoom) ?? throw new NullReferenceException());
232-
233-
activeRect = (Rect)(characteristics.Get(CameraCharacteristics.SensorInfoActiveArraySize) ?? throw new NullReferenceException());
234-
sensorOrientation = (int)(characteristics.Get(CameraCharacteristics.SensorOrientation) ?? throw new NullReferenceException());
235-
236-
var displaySize = new APoint();
237-
Activity.WindowManager?.DefaultDisplay?.GetSize(displaySize);
230+
if (Element != null)
231+
Element.MaxZoom = maxDigitalZoom = (float)(characteristics.Get(CameraCharacteristics.ScalerAvailableMaxDigitalZoom) ?? throw new NullReferenceException());
238232

239-
_ = texture ?? throw new NullReferenceException();
240-
var rotatedViewWidth = texture.Width;
241-
var rotatedViewHeight = texture.Height;
242-
var maxPreviewWidth = displaySize.X;
243-
var maxPreviewHeight = displaySize.Y;
233+
activeRect = (Rect)(characteristics.Get(CameraCharacteristics.SensorInfoActiveArraySize) ?? throw new NullReferenceException());
234+
sensorOrientation = (int)(characteristics.Get(CameraCharacteristics.SensorOrientation) ?? throw new NullReferenceException());
244235

245-
if (sensorOrientation == 90 || sensorOrientation == 270)
246-
{
247-
rotatedViewWidth = texture.Height;
248-
rotatedViewHeight = texture.Width;
249-
maxPreviewWidth = displaySize.Y;
250-
maxPreviewHeight = displaySize.X;
251-
}
236+
var displaySize = new APoint();
237+
Activity.WindowManager?.DefaultDisplay?.GetSize(displaySize);
252238

253-
if (maxPreviewHeight > CameraFragment.maxPreviewHeight)
254-
{
255-
maxPreviewHeight = CameraFragment.maxPreviewHeight;
256-
}
239+
_ = texture ?? throw new NullReferenceException();
240+
var rotatedViewWidth = texture.Width;
241+
var rotatedViewHeight = texture.Height;
242+
var maxPreviewWidth = displaySize.X;
243+
var maxPreviewHeight = displaySize.Y;
257244

258-
if (maxPreviewWidth > CameraFragment.maxPreviewWidth)
259-
{
260-
maxPreviewWidth = CameraFragment.maxPreviewWidth;
261-
}
245+
if (sensorOrientation == 90 || sensorOrientation == 270)
246+
{
247+
rotatedViewWidth = texture.Height;
248+
rotatedViewHeight = texture.Width;
249+
maxPreviewWidth = displaySize.Y;
250+
maxPreviewHeight = displaySize.X;
251+
}
262252

263-
photoSize = GetMaxSize(map.GetOutputSizes((int)ImageFormatType.Jpeg));
264-
videoSize = GetMaxSize(map.GetOutputSizes(Class.FromType(typeof(MediaRecorder))));
265-
previewSize = ChooseOptimalSize(
266-
map.GetOutputSizes(Class.FromType(typeof(SurfaceTexture))) ?? throw new NullReferenceException(),
267-
rotatedViewWidth,
268-
rotatedViewHeight,
269-
maxPreviewWidth,
270-
maxPreviewHeight,
271-
cameraTemplate == CameraTemplate.Record ? videoSize : photoSize);
272-
cameraType = (LensFacing)(int)(characteristics.Get(CameraCharacteristics.LensFacing) ?? throw new NullReferenceException());
273-
274-
if (Resources.Configuration?.Orientation == AOrientation.Landscape)
275-
texture.SetAspectRatio(previewSize.Width, previewSize.Height);
276-
else
277-
texture.SetAspectRatio(previewSize.Height, previewSize.Width);
253+
if (maxPreviewHeight > CameraFragment.maxPreviewHeight)
254+
{
255+
maxPreviewHeight = CameraFragment.maxPreviewHeight;
256+
}
278257

279-
initTaskSource = new TaskCompletionSource<CameraDevice?>();
258+
if (maxPreviewWidth > CameraFragment.maxPreviewWidth)
259+
{
260+
maxPreviewWidth = CameraFragment.maxPreviewWidth;
261+
}
280262

281-
Manager.OpenCamera(
282-
cameraId,
283-
new CameraStateListener
263+
var outputSizes = map.GetOutputSizes(Class.FromType(typeof(SurfaceTexture))) ?? throw new NullReferenceException();
264+
265+
photoSize = GetMaxSize(map.GetOutputSizes((int)ImageFormatType.Jpeg));
266+
videoSize = GetMaxSize(map.GetOutputSizes(Class.FromType(typeof(MediaRecorder))));
267+
previewSize = ChooseOptimalSize(
268+
outputSizes,
269+
rotatedViewWidth,
270+
rotatedViewHeight,
271+
maxPreviewWidth,
272+
maxPreviewHeight,
273+
cameraTemplate == CameraTemplate.Record ? videoSize : photoSize);
274+
cameraType = (LensFacing)(int)(characteristics.Get(CameraCharacteristics.LensFacing) ?? throw new NullReferenceException());
275+
276+
if (Resources.Configuration?.Orientation == AOrientation.Landscape)
277+
texture.SetAspectRatio(previewSize.Width, previewSize.Height);
278+
else
279+
texture.SetAspectRatio(previewSize.Height, previewSize.Width);
280+
281+
initTaskSource = new TaskCompletionSource<CameraDevice?>();
282+
283+
Manager.OpenCamera(
284+
cameraId,
285+
new CameraStateListener
286+
{
287+
OnOpenedAction = device => initTaskSource?.TrySetResult(device),
288+
OnDisconnectedAction = device =>
284289
{
285-
OnOpenedAction = device => initTaskSource?.TrySetResult(device),
286-
OnDisconnectedAction = device =>
287-
{
288-
initTaskSource?.TrySetResult(null);
289-
CloseDevice(device);
290-
},
291-
OnErrorAction = (device, error) =>
292-
{
293-
initTaskSource?.TrySetResult(device);
294-
Element?.RaiseMediaCaptureFailed($"Camera device error: {error}");
295-
CloseDevice(device);
296-
},
297-
OnClosedAction = device =>
298-
{
299-
initTaskSource?.TrySetResult(null);
300-
CloseDevice(device);
301-
}
290+
initTaskSource?.TrySetResult(null);
291+
CloseDevice(device);
302292
},
303-
backgroundHandler);
293+
OnErrorAction = (device, error) =>
294+
{
295+
initTaskSource?.TrySetResult(device);
296+
Element?.RaiseMediaCaptureFailed($"Camera device error: {error}");
297+
CloseDevice(device);
298+
},
299+
OnClosedAction = device =>
300+
{
301+
initTaskSource?.TrySetResult(null);
302+
CloseDevice(device);
303+
}
304+
},
305+
backgroundHandler);
304306

305-
captureSessionOpenCloseLock.Release();
306-
device = await initTaskSource.Task;
307-
initTaskSource = null;
308-
if (device != null)
309-
await PrepareSession();
310-
}
311-
catch (Java.Lang.Exception error)
312-
{
313-
LogError("Failed to open camera", error);
314-
Available = false;
315-
}
316-
finally
317-
{
318-
IsBusy = false;
319-
}
307+
captureSessionOpenCloseLock.Release();
308+
device = await initTaskSource.Task;
309+
initTaskSource = null;
310+
if (device != null)
311+
await PrepareSession();
312+
}
313+
catch (Java.Lang.Exception error)
314+
{
315+
LogError("Failed to open camera", error);
316+
Available = false;
317+
}
318+
finally
319+
{
320+
IsBusy = false;
320321
}
321322
}
322323

@@ -602,7 +603,7 @@ async Task PrepareSession()
602603
OnConfigureFailedAction = captureSession =>
603604
{
604605
tcs.SetResult(null);
605-
Element?.RaiseMediaCaptureFailed("Failed to create captire sesstion");
606+
Element?.RaiseMediaCaptureFailed("Failed to create capture session");
606607
},
607608
OnConfiguredAction = captureSession => tcs.SetResult(captureSession)
608609
},
@@ -1058,7 +1059,17 @@ ASize ChooseOptimalSize(ASize[] choices, int width, int height, int maxWidth, in
10581059
}
10591060

10601061
LogError("Couldn't find any suitable preview size");
1061-
return choices[0];
1062+
1063+
var fallbackChoice = choices[0];
1064+
1065+
if (fallbackChoice.Height > maxHeight || fallbackChoice.Width > maxWidth)
1066+
{
1067+
LogError("Fallback choice is too large, using max preview size");
1068+
1069+
fallbackChoice = new ASize(maxWidth, maxHeight);
1070+
}
1071+
1072+
return fallbackChoice;
10621073
}
10631074
}
10641075
}

0 commit comments

Comments
 (0)