Search code examples
c#windows-phone-8.1windows-phone

How do I rotate captureManager saved photo in WP8.1


I wrote a simple code in C# and VS2013 for Lumia 640 XL WP 8.1, like an example photo app. Not too bad, but it's have an little problem: when the picture saved to the media, then this picture is rotated 90 degrees to left.

Here is my code for setting preview area:

captureManager = new MediaCapture();
await captureManager.InitializeAsync();
captureManager.SetPreviewRotation(VideoRotation.Clockwise90Degrees);
captureManager.SetRecordRotation(VideoRotation.Clockwise90Degrees);
cptElement.Source = captureManager;
await captureManager.StartPreviewAsync();

And here is the code for capture:

ImageEncodingProperties imgFormat = ImageEncodingProperties.CreateJpeg();
StorageFile file = await KnownFolders.PicturesLibrary.CreateFileAsync("Photo.jpg", CreationCollisionOption.GenerateUniqueName);
await captureManager.CapturePhotoToStorageFileAsync(imgFormat, file);

So, you may see, i tried to rotate a finally picture in this commandline:

captureManager.SetRecordRotation(VideoRotation.Clockwise90Degrees);

but it was not worked.

What do I do in this case?

Thanks for your help and sorry for my pure english.


Solution

  • You should be looking at the CameraStarterKit SDK sample. It will show you how to do rotation of:

    Preview:

    /// <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;
    
        // 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);
        props.Properties.Add(RotationKey, rotationDegrees);
        await _mediaCapture.SetEncodingPropertiesAsync(MediaStreamType.VideoPreview, props, null);
    }
    

    Photos:

    /// <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();
    
        try
        {
            Debug.WriteLine("Taking photo...");
            await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
            Debug.WriteLine("Photo taken!");
    
            var photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
    
            await ReencodeAndSavePhotoAsync(stream, photoOrientation);
        }
        catch (Exception ex)
        {
            // File I/O errors are reported as exceptions
            Debug.WriteLine("Exception when taking a photo: {0}", ex.ToString());
        }
    }
    

    And videos:

    /// <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 in Pictures Library
            var videoFile = await KnownFolders.PicturesLibrary.CreateFileAsync("SimpleVideo.mp4", CreationCollisionOption.GenerateUniqueName);
    
            var encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
    
            // Calculate rotation angle, taking mirroring into account if necessary
            var rotationAngle = 360 - ConvertDeviceOrientationToDegrees(GetCameraOrientation());
            encodingProfile.Video.Properties.Add(RotationKey, PropertyValue.CreateInt32(rotationAngle));
    
            Debug.WriteLine("Starting recording...");
    
            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: {0}", ex.ToString());
        }
    }
    

    But you should look at the full sample to see where the orientation/rotation information is coming from, and to get the helper functions as well.