I am writing a UWP application.It's like a simple custom camera with Taking PHOTO Button. It includes an XAML view having captureElement, and page behind the code.
The issue is that Camera opens on 50% of the screen on devices: Lumia 950 and Lumia 950XL as if the Grid containing captureElement is divided into two columns but on other devices, it perfect.
I took help of: Microsoft UWP Samples: Camera Sample
namespace InfoMedia.Views.Posting
{
public sealed partial class PostingCameraView : BasePage
{
private readonly DisplayInformation _displayInformation = DisplayInformation.GetForCurrentView();
private readonly SimpleOrientationSensor _orientationSensor = SimpleOrientationSensor.GetDefault();
private SimpleOrientation _deviceOrientation = SimpleOrientation.NotRotated;
private DisplayOrientations _displayOrientation = DisplayOrientations.Portrait;
private static readonly Guid RotationKey = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1");
private StorageFolder _captureFolder = null;
private readonly DisplayRequest _displayRequest = new DisplayRequest();
private readonly SystemMediaTransportControls _systemMediaControls = SystemMediaTransportControls.GetForCurrentView();
// MediaCapture and its state variables
private MediaCapture _mediaCapture;
private bool _isInitialized;
private bool _isPreviewing;
private bool _mirroringPreview;
private bool _externalCamera;
private bool _isRecording;
private PostingAdViewModel postingAdViewModel;
#region Constructor, lifecycle, and navigation
public PostingCameraView()
{
this.InitializeComponent();
if (ApplicationHelper.GetInstance().DetectDeviceFamily() == CommonServices.Enums.DeviceType.Phone)
{
NavigationCacheMode = NavigationCacheMode.Disabled;
this.Loaded += PostingCameraView_Loaded;
}
}
private async void PostingCameraView_Loaded(object sender, RoutedEventArgs e)
{
postingAdViewModel.IsCameraInitializing = true;
await SetupUiAsync();
await InitializeCameraAsync();
postingAdViewModel.IsCameraInitializing = false;
}
#region Event handlers
private async void SystemMediaControls_PropertyChanged(SystemMediaTransportControls sender, SystemMediaTransportControlsPropertyChangedEventArgs args)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
// Only handle this event if this page is currently being displayed
if (args.Property == SystemMediaTransportControlsProperty.SoundLevel && Frame.CurrentSourcePageType == typeof(MainPage))
{
if (sender.SoundLevel == SoundLevel.Muted)
{
await CleanupCameraAsync();
}
else if (!_isInitialized)
{
await InitializeCameraAsync();
}
}
});
}
private void OrientationSensor_OrientationChanged(SimpleOrientationSensor sender, SimpleOrientationSensorOrientationChangedEventArgs args)
{
if (args.Orientation != SimpleOrientation.Faceup && args.Orientation != SimpleOrientation.Facedown)
{
_deviceOrientation = args.Orientation;
}
}
private async void DisplayInformation_OrientationChanged(DisplayInformation sender, object args)
{
_displayOrientation = sender.CurrentOrientation;
if (_isPreviewing)
{
await SetPreviewRotationAsync();
}
}
#endregion Event handlers
#region MediaCapture methods
private async Task InitializeCameraAsync()
{
Debug.WriteLine("InitializeCameraAsync");
if (_mediaCapture == null)
{
// Attempt to get the back camera if one is available, but use any camera device if not
var cameraDevice = await FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel.Back);
if (cameraDevice == null)
{
Debug.WriteLine("No camera device found!");
return;
}
// Create MediaCapture and its settings
_mediaCapture = new MediaCapture();
// Register for a notification when video recording has reached the maximum time and when something goes wrong
_mediaCapture.RecordLimitationExceeded += MediaCapture_RecordLimitationExceeded;
_mediaCapture.Failed += MediaCapture_Failed;
var settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };
// Initialize MediaCapture
try
{
await _mediaCapture.InitializeAsync(settings);
_isInitialized = true;
}
catch (UnauthorizedAccessException)
{
Debug.WriteLine("Access to the camera is denied. You can change the permissions in mobile settings for camera", "Alert!");
}
// If initialization succeeded, start the preview
if (_isInitialized)
{
// Figure out where the camera is located
if (cameraDevice.EnclosureLocation == null || cameraDevice.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Unknown)
{
// No information on the location of the camera, assume it's an external camera, not integrated on the device
_externalCamera = true;
}
else
{
// Camera is fixed on the device
_externalCamera = false;
// Only mirror the preview if the camera is on the front panel
_mirroringPreview = (cameraDevice.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front);
}
await StartPreviewAsync();
UpdateCaptureControls();
}
}
}
private async Task StartPreviewAsync()
{
// Prevent the device from sleeping while the preview is running
_displayRequest.RequestActive();
// Set the preview source in the UI and mirror it if necessary
PreviewControl.Source = _mediaCapture;
PreviewControl.FlowDirection = _mirroringPreview ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
// Start the preview
await _mediaCapture.StartPreviewAsync();
_isPreviewing = true;
// Initialize the preview to the current orientation
if (_isPreviewing)
{
await SetPreviewRotationAsync();
}
}
private async Task FocusCameraLens()
{
if (_mediaCapture != null)
{
if (_isPreviewing)
{
// test if focus is supported
if (_mediaCapture.VideoDeviceController.FocusControl.Supported)
{
// get the focus control from the mediaCapture object
var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
// try to get full range, but settle for the first supported one.
var focusRange = focusControl.SupportedFocusRanges.Contains(AutoFocusRange.FullRange)
? AutoFocusRange.FullRange
: focusControl.SupportedFocusRanges.FirstOrDefault();
var focusMode = focusControl.SupportedFocusModes.Contains(FocusMode.Auto)
? FocusMode.Auto
: focusControl.SupportedFocusModes.FirstOrDefault();
focusControl.Configure(
new FocusSettings
{
Mode = focusMode,
AutoFocusRange = focusRange
});
try
{
// finally wait for the camera to focus
await focusControl.FocusAsync();
}
catch (Exception _focusExp)
{
//Ignore
}
}
}
}
}
private async Task SetPreviewRotationAsync()
{
// Only need to update the orientation if the camera is mounted on the device
if (_externalCamera) return;
// Calculate which way and how far to rotate the preview
int rotationDegrees = ConvertDisplayOrientationToDegrees(_displayOrientation);
// The rotation direction needs to be inverted if the preview is being mirrored
if (_mirroringPreview)
{
rotationDegrees = (360 - rotationDegrees) % 360;
}
// Add rotation metadata to the preview stream to make sure the aspect ratio / dimensions match when rendering and getting preview frames
var props = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview);
int MFVideoRotation = ConvertVideoRotationToMFRotation(VideoRotation.Clockwise90Degrees);
// props.Properties.Add(RotationKey, rotationDegrees);
props.Properties.Add(RotationKey, PropertyValue.CreateInt32(MFVideoRotation));
await _mediaCapture.SetEncodingPropertiesAsync(MediaStreamType.VideoPreview, props, null);
}
int ConvertVideoRotationToMFRotation(VideoRotation rotation)
{
int MFVideoRotation = 0; // MFVideoRotationFormat::MFVideoRotationFormat_0 in Mfapi.h
switch (rotation)
{
case VideoRotation.Clockwise90Degrees:
MFVideoRotation = 90; // MFVideoRotationFormat::MFVideoRotationFormat_90;
break;
case VideoRotation.Clockwise180Degrees:
MFVideoRotation = 180; // MFVideoRotationFormat::MFVideoRotationFormat_180;
break;
case VideoRotation.Clockwise270Degrees:
MFVideoRotation = 270; // MFVideoRotationFormat::MFVideoRotationFormat_270;
break;
}
return MFVideoRotation;
}
#endregion MediaCapture methods
#region Helper functions
private async Task SetupUiAsync()
{
DisplayInformation.AutoRotationPreferences = DisplayOrientations.Portrait;
if (ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{
await Windows.UI.ViewManagement.StatusBar.GetForCurrentView().HideAsync();
}
_displayOrientation = _displayInformation.CurrentOrientation;
if (_orientationSensor != null)
{
_deviceOrientation = _orientationSensor.GetCurrentOrientation();
}
RegisterEventHandlers();
var picturesLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
this.UpdateLayout();
}
private void UpdateCaptureControls()
{
postingAdViewModel.IsCaptureButtonEnabled = _isPreviewing;
if (_isInitialized && !_mediaCapture.MediaCaptureSettings.ConcurrentRecordAndPhotoSupported)
{
postingAdViewModel.IsCaptureButtonEnabled = !_isRecording;
PhotoButton.Opacity = postingAdViewModel.IsCaptureButtonEnabled ? 1 : 0;
}
}
private void RegisterEventHandlers()
{
if (ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
HardwareButtons.CameraPressed += HardwareButtons_CameraPressed;
}
if (_orientationSensor != null)
{
_orientationSensor.OrientationChanged += OrientationSensor_OrientationChanged;
}
_displayInformation.OrientationChanged += DisplayInformation_OrientationChanged;
_systemMediaControls.PropertyChanged += SystemMediaControls_PropertyChanged;
}
private void UnregisterEventHandlers()
{
if (ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
HardwareButtons.CameraPressed -= HardwareButtons_CameraPressed;
}
if (_orientationSensor != null)
{
_orientationSensor.OrientationChanged -= OrientationSensor_OrientationChanged;
}
_displayInformation.OrientationChanged -= DisplayInformation_OrientationChanged;
_systemMediaControls.PropertyChanged -= SystemMediaControls_PropertyChanged;
}
private static async Task<DeviceInformation> FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel desiredPanel)
{
var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
DeviceInformation desiredDevice = allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredPanel);
return desiredDevice ?? allVideoDevices.FirstOrDefault();
}
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, StorageFile file, PhotoOrientation photoOrientation)
{
using (var inputStream = stream)
{
var decoder = await BitmapDecoder.CreateAsync(inputStream);
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
var properties = new BitmapPropertySet { { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
await encoder.BitmapProperties.SetPropertiesAsync(properties);
await encoder.FlushAsync();
}
}
}
#endregion Helper functions
#region Rotation helpers
private SimpleOrientation GetCameraOrientation()
{
if (_externalCamera)
{
return SimpleOrientation.NotRotated;
}
var result = _deviceOrientation;
if (_displayInformation.NativeOrientation == DisplayOrientations.Portrait)
{
switch (result)
{
case SimpleOrientation.Rotated90DegreesCounterclockwise:
result = SimpleOrientation.NotRotated;
break;
case SimpleOrientation.Rotated180DegreesCounterclockwise:
result = SimpleOrientation.Rotated90DegreesCounterclockwise;
break;
case SimpleOrientation.Rotated270DegreesCounterclockwise:
result = SimpleOrientation.Rotated180DegreesCounterclockwise;
break;
case SimpleOrientation.NotRotated:
result = SimpleOrientation.Rotated270DegreesCounterclockwise;
break;
}
}
if (_mirroringPreview)
{
switch (result)
{
case SimpleOrientation.Rotated90DegreesCounterclockwise:
return SimpleOrientation.Rotated270DegreesCounterclockwise;
case SimpleOrientation.Rotated270DegreesCounterclockwise:
return SimpleOrientation.Rotated90DegreesCounterclockwise;
}
}
return result;
}
private static int ConvertDeviceOrientationToDegrees(SimpleOrientation orientation)
{
switch (orientation)
{
case SimpleOrientation.Rotated90DegreesCounterclockwise:
return 90;
case SimpleOrientation.Rotated180DegreesCounterclockwise:
return 180;
case SimpleOrientation.Rotated270DegreesCounterclockwise:
return 270;
case SimpleOrientation.NotRotated:
default:
return 0;
}
}
private static int ConvertDisplayOrientationToDegrees(DisplayOrientations orientation)
{
switch (orientation)
{
case DisplayOrientations.Portrait:
return 90;
case DisplayOrientations.LandscapeFlipped:
return 180;
case DisplayOrientations.PortraitFlipped:
return 270;
case DisplayOrientations.Landscape:
default:
return 0;
}
}
private static PhotoOrientation ConvertOrientationToPhotoOrientation(SimpleOrientation orientation)
{
switch (orientation)
{
case SimpleOrientation.Rotated90DegreesCounterclockwise:
return PhotoOrientation.Rotate90;
case SimpleOrientation.Rotated180DegreesCounterclockwise:
return PhotoOrientation.Rotate180;
case SimpleOrientation.Rotated270DegreesCounterclockwise:
return PhotoOrientation.Rotate270;
case SimpleOrientation.NotRotated:
default:
return PhotoOrientation.Normal;
}
}
#endregion Rotation helpers
}
}
What is causing this issue?
Solved:
It hides the soft Navigaiton Bar, and aspect ratio is maintained to captureElement, and camera works fine