Camera preview rotation

Apr 10, 2013 at 3:59 AM
I have a Dell Latitude 10 tablet. The built-in camera app is able to seamlessly show its fullscreen live preview in any orientation of the tablet. Changing to portrait mode behaves as expected. It freezes the preview, then when the rotation is complete, it goes live again with the subject centered exactly where it was in landscape mode. It's impressive.

I am not using the WinRT XAML Toolkit's camera preview code, but both your sample and the MSDN simple capture sample do not rotate the preview. I am trying to do this based on the simple capture code but rotating the fullscreen preview element has unexpected results. It is shifted inexplicably to the top or bottom, and is scaled down. Any attempts to stretch it or move it cause it to be placed partly offscreen or to be cropped.

Fighting this made me wonder if you have had any experience with this or if the WinRT XAML Toolkit has a way to handle live preview rotation. Do you have any insight?
Coordinator
Apr 10, 2013 at 6:03 AM
I looked around and it seems like indeed the CameraCaptureUI rotates the preview so that regardless of screen orientation - it is oriented correctly. I started fiddling with the CameraCaptureControl template and it seems like you could fairly reliably control the rotation of the preview using the LayoutTransformControl from the toolkit which uses RenderTransform internally, but also makes the calculations to update the layout properties that makes it easier to keep within bounds. Note that it doesn't support CompositeTransform though, so you need to use TransformGroup if you want to achieve more than just rotation - e.g. to enable preview mirroring:
<controls:LayoutTransformControl>
    <controls:LayoutTransformControl.Transform>
        <TransformGroup>
            <ScaleTransform
                x:Name="PART_ScaleTransform"
                ScaleX="-1"/>
            <RotateTransform
                x:Name="PART_RotateTransform"
                Angle="0"/>
        </TransformGroup>
    </controls:LayoutTransformControl.Transform>
    <CaptureElement
        x:Name="PART_CaptureElement"
        Stretch="Uniform" />
</controls:LayoutTransformControl>
Apr 10, 2013 at 4:07 PM
Thank you for pointing me in the right direction. I was able to make it work with a rotation transform and a scale transform. The preview needs to be scaled up in portrait view. The scale is equivalent to the aspect ratio of the display.
double fScale = Math.Max(Window.Current.Bounds.Width, Window.Current.Bounds.Height) / Math.Min(Window.Current.Bounds.Width, Window.Current.Bounds.Height);
            
            var orientation = DisplayProperties.CurrentOrientation;
            if (orientation == DisplayOrientations.Portrait)
            {
                previewRotate.Angle = -90;
                previewScale.ScaleX = fScale;
                previewScale.ScaleY = fScale;
            }
            else if (orientation == DisplayOrientations.PortraitFlipped)
            {
                previewRotate.Angle = 90;
                previewScale.ScaleX = fScale;
                previewScale.ScaleY = fScale;
            }
            else if (orientation == DisplayOrientations.LandscapeFlipped)
            {
                previewRotate.Angle = 180;
                previewScale.ScaleX = 1.0;
                previewScale.ScaleY = 1.0;
            }
            else
            {
                previewRotate.Angle = 0;
                previewScale.ScaleX = 1.0;
                previewScale.ScaleY = 1.0;
            }
I still need to handle cases for which camera is selected since the mirroring and rotation are opposite. But this code works smoothly.