Для корректного отображения видоискателя, необходимо две информации:
- ориентации: просмотр ориентации изображения по отношению к вашей странице ориентации
- Масштаб: коэффициент между размером изображения предварительного просмотра и управления XAML.
В первом вам нужен холст с VideoBrush в качестве фона
<Canvas x:Name="viewfinderCanvas" Width="480" Height="800" >
<Canvas.Background>
<VideoBrush x:Name="viewfinderBrush" Stretch="None" />
</Canvas.Background>
</Canvas>
Вы должны использовать Stretch = "None" или XAML будет применять шкалу на viewbrush. Теперь вам нужно преобразование viewfinderBrush, чтобы отобразить его правильно. По умолчанию центр холста соответствует центру предварительного просмотра, поэтому нам нужно вычислить угол, масштабный коэффициент и использовать центр холста в качестве центра преобразования.
Для вычисления угла нужно:
код:
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;
}
}
Масштаб просто фактор между размерностью холста и размера предварительного просмотра изображения:
//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;
- При использовании максимального коэффициента, вы делаете Fit out => scale = Math.Max (s1, s2)
- Если вы используете минимальный коэффициент, вы делаете В приступе => шкала = Math.min (s1, s2)
Передняя и задняя камера имеет свое направление глаз противоположное. Поэтому, чтобы правильно отобразить переднюю камеру, вам нужно применить зеркало в одном измерении. Ориентация датчика WP8 обычно равна 90 °, поэтому размер Y противоположный.
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
}
Вы можете найти последнюю версию образца на GitHub: https://github.com/yan-verdavaine/wp8-sample/tree/master/Imaging/ViewFinder
Странно голосовать -1 по коду, который отвечает на исходную проблему: /. Если я ошибаюсь, не могли бы вы объяснить мне? – yan
Ссылка только ответы не предпочтительны на SO, поскольку содержимое, на которое они указывают, может быть изменено или отменено, попробуйте добавить код для своего образца к вашему ответу. – Amicable
Хорошо спасибо. Я добавлю больше объяснений позже. – yan