locked
MediaCapture taken photos always rotated 90 degrees

    Question

  • Why is the MediaCapture preview is 90 degrees counter clockwise? I can set the preview rotate but the image captured is never oriented correctly. MediaCapture.SetRecordRotation has no effect at all.

    How to have a simple photo taking capability that's at least will capture a photo correctly?

    Simply place a CaptureElement on a page and add a button to take photo.

    <Grid x:Name="LayoutRoot">
    
            <CaptureElement x:Name="CaptureElement_Main" Stretch="UniformToFill" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                <AppBarButton x:Name="AppBarButton_Capture" Icon="Camera" IsCompact="True" Click="AppBarButton_Capture_Click"/>
    </Grid>

    Code behind

    private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
    {
        await InitCaptureSettingsAsync();
        await PreviewCameraAsync();
    }
    
    private MediaCapture _mediaCapture = null;
    private bool _isCameraReady = false;
    private bool _isCameraPreviewing = false;
    
    private async Task InitCaptureSettingsAsync()
    {
        var _devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(Windows.Devices.Enumeration.DeviceClass.VideoCapture);
    
        if (_devices.Count > 0)
        {
            MediaCaptureInitializationSettings _captureInitSettings = new MediaCaptureInitializationSettings();
            _captureInitSettings.AudioDeviceId = "";
            _captureInitSettings.VideoDeviceId = "";
            _captureInitSettings.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.Video;
            _captureInitSettings.PhotoCaptureSource = Windows.Media.Capture.PhotoCaptureSource.VideoPreview;
    
            bool _hasRearCamera = false;
            foreach (var camera in _devices)
            {
                if (camera.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back)
                {
                    _captureInitSettings.VideoDeviceId = camera.Id;
                    _hasRearCamera = true;
                }
            }
    
            if (_hasRearCamera)
            {
                if(_mediaCapture == null)
                    _mediaCapture = new Windows.Media.Capture.MediaCapture();
    
                try
                {
                    await _mediaCapture.InitializeAsync(_captureInitSettings);
                }
                catch (Exception)
                {
                    return;
                }
    
                await _mediaCapture.VideoDeviceController.FocusControl.UnlockAsync();
                //_mediaCapture.SetPreviewRotation(VideoRotation.Clockwise90Degrees);
                //_mediaCapture.SetRecordRotation(VideoRotation.Clockwise90Degrees);
                _mediaCapture.VideoDeviceController.FocusControl.Configure(new FocusSettings { Mode = FocusMode.Auto, AutoFocusRange = AutoFocusRange.FullRange });
    
                var resolutions = _mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo);
                if (resolutions.Count > 1)
                {
                    var hires = resolutions.OrderByDescending(item => ((VideoEncodingProperties)item).Width).First();
                    await _mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, hires);
                }
    
                _isCameraReady = true;
            }
        }
    }
    
    private async Task PreviewCameraAsync()
    {
        if (_isCameraReady)
        {
            CaptureElement_Main.Source = _mediaCapture;
            await _mediaCapture.StartPreviewAsync();
            _isCameraPreviewing = true;
        }
    }
    
    private async void AppBarButton_Capture_Click(object sender, RoutedEventArgs e)
    {
        await _mediaCapture.VideoDeviceController.FocusControl.FocusAsync();
        StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("picture.jpg", CreationCollisionOption.ReplaceExisting);
        await _mediaCapture.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), file);
    }


    • Edited by chinlj Saturday, September 13, 2014 10:22 AM
    Saturday, September 13, 2014 10:20 AM

Answers

  • In case anyone come finding the answer, the way I found is to write the meta data to the bitmap created after capturing a shot.

    var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(_inputStream);
    var encoder = await Windows.Graphics.Imaging.BitmapEncoder.CreateForInPlacePropertyEncodingAsync(decoder);
    var propertySet = new Windows.Graphics.Imaging.BitmapPropertySet();
    var orientationValue = new Windows.Graphics.Imaging.BitmapTypedValue(_photoOrientation, PropertyType.UInt16);
    propertySet.Add("System.Photo.Orientation", orientationValue);
    
    try
    {
    await encoder.BitmapProperties.SetPropertiesAsync(propertySet);
    await encoder.FlushAsync();
    }
    catch (Exception err)
    {.....


    Tuesday, September 16, 2014 3:51 PM

All replies

  • CameraCaptureTask cameraCaptureTask = new CameraCaptureTask();
           
           
    
    
    void cameraCaptureTask_Completed(object sender, PhotoResult e)
    {
        if (e.TaskResult == TaskResult.OK)
        {
            BitmapImage bitmap = new BitmapImage();
            bitmap.SetSource(e.ChosenPhoto);
            string tempJpeg = "myWallpaper.jpeg";
            using (IsolatedStorageFile myIsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (myIsolatedStorageFile.FileExists(tempJpeg))
                {
                    myIsolatedStorageFile.DeleteFile(tempJpeg);
    
                }
                IsolatedStorageFileStream filestream = myIsolatedStorageFile.CreateFile(tempJpeg);
                StreamResourceInfo sri = null;
                Uri uri = new Uri(tempJpeg, UriKind.Relative);
    
                sri = Application.GetResourceStream(uri);
                WriteableBitmap wb = new WriteableBitmap(bitmap);
                Extensions.SaveJpeg(wb, filestream, wb.PixelWidth, wb.PixelHeight, 0, 90);
                filestream.Close();
            }
            lockscreenChange(tempJpeg);
        }
        //throw new NotImplementedException();
    }
    
    
    
    

    Hope this will help

    Muhammad Asad.


    Saturday, September 13, 2014 11:13 AM
  • Hi, is that Silverlight code? I'm on Windows Runtime though.

    I'm able to capture and save the image, just can't figure out the orientation.

    Saturday, September 13, 2014 1:46 PM
  • In case anyone come finding the answer, the way I found is to write the meta data to the bitmap created after capturing a shot.

    var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(_inputStream);
    var encoder = await Windows.Graphics.Imaging.BitmapEncoder.CreateForInPlacePropertyEncodingAsync(decoder);
    var propertySet = new Windows.Graphics.Imaging.BitmapPropertySet();
    var orientationValue = new Windows.Graphics.Imaging.BitmapTypedValue(_photoOrientation, PropertyType.UInt16);
    propertySet.Add("System.Photo.Orientation", orientationValue);
    
    try
    {
    await encoder.BitmapProperties.SetPropertiesAsync(propertySet);
    await encoder.FlushAsync();
    }
    catch (Exception err)
    {.....


    Tuesday, September 16, 2014 3:51 PM
  • Yes its silverlight code snippet

    Muhammad Asad.

    Tuesday, September 16, 2014 4:30 PM