/// <summary> /// Takes a photo to a StorageFile and adds rotation metadata to it /// </summary> /// <returns></returns> private async Task TakePhotoAsync() { // While taking a photo, keep the video button enabled only if the camera supports simultaneously taking pictures and recording video VideoButton.IsEnabled = _mediaCapture.MediaCaptureSettings.ConcurrentRecordAndPhotoSupported; // Make the button invisible if it's disabled, so it's obvious it cannot be interacted with VideoButton.Opacity = VideoButton.IsEnabled ? 1 : 0; var stream = new InMemoryRandomAccessStream(); Debug.WriteLine("Taking photo..."); await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream); try { var file = await _captureFolder.CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption.GenerateUniqueName); Debug.WriteLine("Photo taken! Saving to " + file.Path); var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(_rotationHelper.GetCameraCaptureOrientation()); await ReencodeAndSavePhotoAsync(stream, file, photoOrientation); Debug.WriteLine("Photo saved!"); } catch (Exception ex) { // File I/O errors are reported as exceptions Debug.WriteLine("Exception when taking a photo: " + ex.ToString()); } // Done taking a photo, so re-enable the button VideoButton.IsEnabled = true; VideoButton.Opacity = 1; }
/// <summary> /// Records an MP4 video to a StorageFile and adds rotation metadata to it /// </summary> /// <returns></returns> private async Task StartRecordingAsync() { try { // Create storage file for the capture var videoFile = await localFolder.CreateFileAsync($"Video.mp4", CreationCollisionOption.GenerateUniqueName); var encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto); // Calculate rotation angle, taking mirroring into account if necessary var rotationAngle = CameraRotationHelper.ConvertSimpleOrientationToClockwiseDegrees(rotationHelper.GetCameraCaptureOrientation()); encodingProfile?.Video?.Properties.Add(RotationKey, PropertyValue.CreateInt32(rotationAngle)); Debug.WriteLine("Starting recording to " + videoFile.Path); await mediaCapture.StartRecordToStorageFileAsync(encodingProfile, videoFile); isRecording = true; Debug.WriteLine("Started recording!"); } catch (Exception ex) { // File I/O errors are reported as exceptions Debug.WriteLine("Exception when starting video recording: " + ex.ToString()); } }
/// <summary> /// Cleans up the camera resources (after stopping any video recording and/or preview if necessary) and unregisters from MediaCapture events /// </summary> /// <returns></returns> private async Task CleanupCameraAsync() { Debug.WriteLine("CleanupCameraAsync"); if (_isInitialized) { if (_isPreviewing) { // The call to stop the preview is included here for completeness, but can be // safely removed if a call to MediaCapture.Dispose() is being made later, // as the preview will be automatically stopped at that point await StopPreviewAsync(); } _isInitialized = false; } if (_mediaCapture != null) { _mediaCapture.RecordLimitationExceeded -= MediaCapture_RecordLimitationExceeded; _mediaCapture.Failed -= MediaCapture_Failed; _mediaCapture.Dispose(); _mediaCapture = null; } if (_rotationHelper != null) { _rotationHelper.OrientationChanged -= RotationHelper_OrientationChanged; _rotationHelper = null; } }
public async Task StartAsync() { m_isRecording = true; if (m_isVideo) { var profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto); var rotationAngle = CameraRotationHelper.ConvertSimpleOrientationToClockwiseDegrees(_rotationHelper.GetCameraCaptureOrientation()); profile.Video.Properties.Add(new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1"), PropertyValue.CreateInt32(rotationAngle)); m_lowLag = await m_mediaCapture.PrepareLowLagRecordToStorageFileAsync(profile, m_file); await m_lowLag.StartAsync(); } else { var wavEncodingProfile = MediaEncodingProfile.CreateWav(AudioEncodingQuality.High); wavEncodingProfile.Audio.BitsPerSample = 16; wavEncodingProfile.Audio.SampleRate = 48000; wavEncodingProfile.Audio.ChannelCount = 1; m_opusSink = await OpusCodec.CreateMediaSinkAsync(m_file); await m_mediaCapture.StartRecordToCustomSinkAsync(wavEncodingProfile, m_opusSink); } }
/// <summary> /// Takes a photo to a StorageFile and adds rotation metadata to it /// </summary> /// <returns></returns> private async Task TakePhotoAsync() { var stream = new InMemoryRandomAccessStream(); Debug.WriteLine("Taking photo..."); await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream); try { var file = await _captureFolder.CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption.GenerateUniqueName); Debug.WriteLine("Photo taken! Saving to " + file.Path); var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(_rotationHelper.GetCameraCaptureOrientation()); await ReencodeAndSavePhotoAsync(stream, file, photoOrientation); PickImage.LoadImagesFromFileClicked(file); Debug.WriteLine("Photo saved!"); } catch (Exception ex) { // File I/O errors are reported as exceptions Debug.WriteLine("Exception when taking a photo: " + ex.ToString()); } }
/// <summary> /// Uses the current device orientation in space and page orientation on the screen to calculate the rotation /// transformation to apply to the controls /// </summary> private void UpdateButtonOrientation() { // Rotate the buttons in the UI to match the rotation of the device var angle = CameraRotationHelper.ConvertSimpleOrientationToClockwiseDegrees(rotationHelper.GetUiOrientation()); var transform = new RotateTransform { Angle = angle }; // The RenderTransform is safe to use (i.e. it won't cause layout issues) in this case, because these buttons have a 1:1 aspect ratio VideoButton.RenderTransform = transform; }
private async Task SetPreviewRotationAsync() { if (!_externalCamera) { // Add rotation metadata to the preview stream to make sure the aspect ratio / dimensions match when rendering and getting preview frames var rotation = _rotationHelper.GetCameraPreviewOrientation(); var props = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview); Guid RotationKey = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1"); props.Properties.Add(RotationKey, CameraRotationHelper.ConvertSimpleOrientationToClockwiseDegrees(rotation)); await _mediaCapture.SetEncodingPropertiesAsync(MediaStreamType.VideoPreview, props, null); } }
private async static void CheckCamera() { DeviceInformation _cameraDevice; var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture); DeviceInformation desiredDevice = allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front); _cameraDevice = desiredDevice ?? allVideoDevices.FirstOrDefault(); var crh = new CameraRotationHelper(_cameraDevice.EnclosureLocation); crh.OrientationChanged += OnOrientationChanged; Debug.WriteLine($"{crh.GetCameraCaptureOrientation()}"); }
/// <summary> /// Gets the current orientation of the UI in relation to the device (when AutoRotationPreferences cannot be honored) and applies a corrective rotation to the preview /// </summary> private async Task SetPreviewRotationAsync() { // Only need to update the orientation if the camera is mounted on the device if (_externalCamera) { return; } // Add rotation metadata to the preview stream to make sure the aspect ratio / dimensions match when rendering and getting preview frames var rotation = _rotationHelper.GetCameraPreviewOrientation(); var props = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview); props.Properties.Add(RotationKey, CameraRotationHelper.ConvertSimpleOrientationToClockwiseDegrees(rotation)); await _mediaCapture.SetEncodingPropertiesAsync(MediaStreamType.VideoPreview, props, null); }
private async void RotationHelper_OrientationChanged(object sender, bool updatePreview) { if (updatePreview) { await SetPreviewRotationAsync(); } await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // Rotate the buttons in the UI to match the rotation of the device var angle = CameraRotationHelper.ConvertSimpleOrientationToClockwiseDegrees(_rotationHelper.GetUIOrientation()); var transform = new RotateTransform { Angle = angle }; // The RenderTransform is safe to use (i.e. it won't cause layout issues) in this case, because these buttons have a 1:1 aspect ratio Capture.RenderTransform = transform; Capture.RenderTransform = transform; }); }
public async void CapturePhoto_Click(object sender, RoutedEventArgs e) { //Getting access to Pictures folder var myPictures = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures); //Createing the file that will be saved StorageFile file = await myPictures.SaveFolder.CreateFileAsync("night-photo.jpg", CreationCollisionOption.GenerateUniqueName); //Capture a photo to the stream using (var captureStream = new InMemoryRandomAccessStream()) { //Common encoding with JPEG format await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), captureStream); using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite)) { //Decode the image from the memory stream var decoder = await BitmapDecoder.CreateAsync(captureStream); //Encode the image to file var encoder = await BitmapEncoder.CreateForTranscodingAsync(fileStream, decoder); //Getting the current orientation of the device var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(_rotationHelper.GetCameraCaptureOrientation()); //Including metadata about the photo in the image file var properties = new BitmapPropertySet { { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } }; await encoder.BitmapProperties.SetPropertiesAsync(properties); await encoder.FlushAsync(); } } }
public async Task SetPreviewRotationAsync() { // Only need to update the orientation if the camera is mounted on the device if (_externalCamera || _rotationHelper == null || m_mediaCapture == null) { return; } // Add rotation metadata to the preview stream to make sure the aspect ratio / dimensions match when rendering and getting preview frames var rotation = _rotationHelper.GetCameraPreviewOrientation(); var props = m_mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview); props.Properties.Add(new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1"), CameraRotationHelper.ConvertSimpleOrientationToClockwiseDegrees(rotation)); await m_mediaCapture.SetEncodingPropertiesAsync(MediaStreamType.VideoPreview, props, null); }
/// <summary> /// Initializes the MediaCapture, registers events, gets camera device information for mirroring and rotating, starts preview and unlocks the UI /// </summary> /// <returns></returns> 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("The app was denied access to the camera"); } // 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); } // Initialize rotationHelper _rotationHelper = new CameraRotationHelper(cameraDevice.EnclosureLocation); _rotationHelper.OrientationChanged += RotationHelper_OrientationChanged; await StartPreviewAsync(); UpdateCaptureControls(); } } }
private async Task InitializeCameraAsync() { if (_mediaCapture == null) { try { // Get the camera devices var cameraDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture); // try to get the front facing device for a phone var FrontFacingDevice = cameraDevices.FirstOrDefault ( c => c.EnclosureLocation?.Panel == Windows.Devices.Enumeration.Panel.Front ); // but if that doesn't exist, take the first camera device available var preferredDevice = FrontFacingDevice ?? cameraDevices.FirstOrDefault(); if (preferredDevice.EnclosureLocation == null || preferredDevice.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Unknown) { _externalCamera = true; } else { _externalCamera = false; _mirroringPreview = (preferredDevice.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front); } _mirroringPreview = true; // Create MediaCapture _mediaCapture = new MediaCapture(); // Initialize MediaCapture and settings await _mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings { VideoDeviceId = preferredDevice.Id }); _rotationHelper = new CameraRotationHelper(preferredDevice.EnclosureLocation); _rotationHelper.OrientationChanged += RotationHelper_OrientationChanged; // Set the preview source for the CaptureElement PreviewControl.Source = _mediaCapture; PreviewControl.FlowDirection = _mirroringPreview ? FlowDirection.RightToLeft : FlowDirection.LeftToRight; // Start viewing through the CaptureElement await _mediaCapture.StartPreviewAsync(); await SetPreviewRotationAsync(); } catch (UnauthorizedAccessException) { // This will be thrown if the user denied access to the camera in privacy settings System.Diagnostics.Debug.WriteLine("This app was denied access to the camera"); var dialog = new Windows.UI.Popups.MessageDialog("This app was denied access to the camera", "Permission Denied"); await dialog.ShowAsync(); CoreApplication.Exit(); } catch (NullReferenceException ex) { System.Diagnostics.Debug.WriteLine("MediaCapture initialization failed. {0}", ex.Message); var dialog = new Windows.UI.Popups.MessageDialog("Please connect a camera device to proceed.", "Camera does not exists"); await dialog.ShowAsync(); //CoreApplication.Exit(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("MediaCapture initialization failed. {0}", ex.Message); var dialog = new Windows.UI.Popups.MessageDialog(ex.Message, "MediaCapture initialization failed."); await dialog.ShowAsync(); CoreApplication.Exit(); } } }