Matt
Matt

Reputation: 4603

rotation of videobrush for photocapturedevice

I'm having some problems with the orientation of my videobrush displaying the photocapturedevice on my phone. It actually should be as flexible as the built-in camera application, which means it should work for

At least one of these is always wrong. I tried https://projects.developer.nokia.com/cameraexplorer to get it work, but even it has the best approach, it's not working for me on different page orientations and front camera is rotating wrong way (counterclockwise when i rotate my phone clockwise, so I'm upside-down).

Is there any code-snippet with a complete working camera videobrush?

Upvotes: 2

Views: 1658

Answers (3)

yan
yan

Reputation: 124

To display correctly the viewfinder, you need two informations :

  • orientation : preview picture orientation relative to your page orientation
  • Scale : factor between preview picture size and xaml control.

In first you need a canvas with the videobrush as background

<Canvas x:Name="viewfinderCanvas" Width="480" Height="800" >
    <Canvas.Background>
        <VideoBrush x:Name="viewfinderBrush"  Stretch="None" />
    </Canvas.Background>
</Canvas>

You must use Stretch="None" or XAML will apply scale on the viewbrush. Now you need the viewfinderBrush transformation to display it correctly. By default, the canvas center correspond to the preview picture center,so we need to compute an angle, a scale factor and use the canvas center as the transform center.

To compute the angle you need :

  • the sensor orientation relative to the device Portrait orientation. This value is given by PhotoCaptureDevice.SensorRotationInDegrees property.
  • your page orientation relative to the device Portrait orientation.

code :

double ComputeAngle(PageOrientation orientation)
{
    if ((orientation & PageOrientation.Portrait) == PageOrientation.Portrait)
    {
        return  m_captureDevice.SensorRotationInDegrees;
    }
    else if ((orientation & PageOrientation.LandscapeLeft) == PageOrientation.LandscapeLeft)
    {
        return m_captureDevice.SensorRotationInDegrees - 90;
    }
    else //PageOrientation.LandscapeRight
    {
        return m_captureDevice.SensorRotationInDegrees + 90;
    }
}

The scale is simply the factor between the canvas dimension and the preview picture dimension :

//orient preview picture size from the computed anle.
var tmp = new CompositeTransform(){Rotation = ComputeAngle(currentPageOrientation)};
var previewSize = tmp.TransformBounds (new Rect(new Point(), new Size(m_captureDevice.PreviewResolution.Width, m_captureDevice.PreviewResolution.Height))).Size;
double s1 = viewfinderCanvas.Width/ (double)previewSize.Width;
double s2 = viewfinderCanvas.Height/ (double)previewSize.Height;
  • If you use the maximum factor, you make a Fit out => scale = Math.Max(s1, s2)
  • If you use the minimum factor, you make a Fit In => scale = Math.Min(s1, s2)

The Front and the back camera have their eye direction opposite. So to display correctly the front camera you need to apply a mirror in one dimension. On WP8 sensor orientation is generally 90° so the Y dimension are opposite.

if (sensorLocation == CameraSensorLocation.Back)
{
    viewfinderBrush.Transform = new CompositeTransform() { 
                        Rotation = ComputeAngle(currentPageOrientation), 
                        CenterX = viewfinderCanvas.Width / 2, 
                        CenterY = viewfinderCanvas.Height / 2, 
                        ScaleX = scale, 
                        ScaleY = scale };
}
else
{
    viewfinderBrush.Transform = new CompositeTransform() { 
                        Rotation = ComputeAngle(currentPageOrientation), 
                        CenterX = viewfinderCanvas.Width / 2, 
                        CenterY = viewfinderCanvas.Height / 2, 
                        ScaleX =  scale, 
                        ScaleY = -1 * scale };//Y mirror 
}

You can find the last version of the sample on github : https://github.com/yan-verdavaine/wp8-sample/tree/master/Imaging/ViewFinder

Upvotes: 7

Vahagn Nahapetyan
Vahagn Nahapetyan

Reputation: 1357

The question is old, but anyway there is no answer in the web regarding wrong direction, when using front camera. To solve this issue, you need to change the direction of VideBrush X axis. Here is the code snippet on how to do it:

if (cameraType == CameraType.Primary)
            {
                viewfinderBrush.RelativeTransform =
                    new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 };
            }
            else
            {
                viewfinderBrush.RelativeTransform =
                                       new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90, ScaleX = -1 };                    
            } 

Upvotes: 3

Could you solve this problem? I recognized the same behavior, when the front camera was used.

I applied a rotate transform (angle = 180°) on a Rectangle (which hosts the videobrush element), and it worked. I've also changed the value of the EncodeWithOrientation property on my AudioVideoCaptureDevice object, and the recorded movie was also OK. This solution only works in portrait mode, however when you change back to landscape, all goes wrong, so this tecnique doesn't really solve the problem. Maybe this is a bug in the SDK?

Upvotes: 0

Related Questions