2

出于某种原因,当我将手机设置为横向模式时,相机预览是颠倒的(水平翻转)。我正在使用 Xamarin 移植的示例项目;AVCam条码

我最终通过在横向使用 GeometryFlipped 提出了一个半完整的修复。但是,现在绘制的条形码在横向模式下没有绘制在正确的位置。

  1. 这是设备/操作系统问题还是示例不完整?
  2. 纠正此问题的推荐方法是什么?

    public override void ViewWillTransitionToSize (CGSize toSize, IUIViewControllerTransitionCoordinator coordinator)
    {
        base.ViewWillTransitionToSize (toSize, coordinator);
    
        var videoPreviewLayerConnection = PreviewView.VideoPreviewLayer.Connection;
        if (videoPreviewLayerConnection != null) {
            var deviceOrientation = UIDevice.CurrentDevice.Orientation;
            if (!deviceOrientation.IsPortrait () && !deviceOrientation.IsLandscape ())
                return;
    
            var newVideoOrientation = VideoOrientationFor (deviceOrientation);
            var oldSize = View.Frame.Size;
            var oldVideoOrientation = videoPreviewLayerConnection.VideoOrientation;
            videoPreviewLayerConnection.VideoOrientation = newVideoOrientation;
    
            //THIS IS THE HALF FIX I CAME UP WITH
            if (deviceOrientation.IsLandscape())
                videoPreviewLayerConnection.VideoPreviewLayer.GeometryFlipped = true;
            else
                videoPreviewLayerConnection.VideoPreviewLayer.GeometryFlipped = false;
            //END FIX
    
            // When we transition to the new size, we need to adjust the region
            // of interest's origin and size so that it stays anchored relative
            // to the camera.
            coordinator.AnimateAlongsideTransition (context => {
                var oldRegion = PreviewView.RegionOfInterest;
                var newRegion = new CGRect ();
    
                if (oldVideoOrientation == LandscapeRight && newVideoOrientation == LandscapeLeft) {
                    newRegion = oldRegion.WithX (oldSize.Width - oldRegion.X - oldRegion.Width);
                } else if (oldVideoOrientation == LandscapeRight && newVideoOrientation == Portrait) {
                    newRegion.X = toSize.Width - oldRegion.Y - oldRegion.Height;
                    newRegion.Y = oldRegion.X;
                    newRegion.Width = oldRegion.Height;
                    newRegion.Height = oldRegion.Width;
                } else if (oldVideoOrientation == LandscapeLeft && newVideoOrientation == LandscapeRight) {
                    newRegion = oldRegion.WithX (oldSize.Width - oldRegion.X - oldRegion.Width);
                } else if (oldVideoOrientation == LandscapeLeft && newVideoOrientation == Portrait) {
                    newRegion.X = oldRegion.Y;
                    newRegion.Y = oldSize.Width - oldRegion.X - oldRegion.Width;
                    newRegion.Width = oldRegion.Height;
                    newRegion.Height = oldRegion.Width;
                } else if (oldVideoOrientation == Portrait && newVideoOrientation == LandscapeRight) {
                    newRegion.X = oldRegion.Y;
                    newRegion.Y = toSize.Height - oldRegion.X - oldRegion.Width;
                    newRegion.Width = oldRegion.Height;
                    newRegion.Height = oldRegion.Width;
                } else if (oldVideoOrientation == Portrait && newVideoOrientation == LandscapeLeft) {
                    newRegion.X = oldSize.Height - oldRegion.Y - oldRegion.Height;
                    newRegion.Y = oldRegion.X;
                    newRegion.Width = oldRegion.Height;
                    newRegion.Height = oldRegion.Width;
                }
    
                PreviewView.SetRegionOfInterestWithProposedRegionOfInterest (newRegion);
            }, context => {
                sessionQueue.DispatchAsync (() => {
                    metadataOutput.RectOfInterest = PreviewView.VideoPreviewLayer.MapToLayerCoordinates (PreviewView.RegionOfInterest);
                });
                // Remove the old metadata object overlays.
                RemoveMetadataObjectOverlayLayers ();
            });
        }
    }
    

编辑

AVCaptureVideoOrientation VideoOrientationFor (UIDeviceOrientation deviceOrientation)
{
    switch (deviceOrientation) {
    case UIDeviceOrientation.Portrait:
        return Portrait;
    case UIDeviceOrientation.PortraitUpsideDown:
        return PortraitUpsideDown;
    case UIDeviceOrientation.LandscapeLeft:
        return LandscapeLeft;
    case UIDeviceOrientation.LandscapeRight:
        return LandscapeRight;
    default:
        throw new InvalidProgramException ();
    }
}
4

1 回答 1

2

设备和视频方向对于横向具有不同的含义。

文档说(用于视频)

案例景观左

表示视频应水平定向,右上。

案例景观右

指示视频应水平放置,左上角。

设备方向说:

案例景观左

设备处于横向模式,设备直立,主页按钮位于右侧。

案例景观右

设备处于横向模式,设备直立,主页按钮位于左侧。

因此,您需要更改为:

case UIDeviceOrientation.LandscapeLeft:
    return LandscapeRight;
case UIDeviceOrientation.LandscapeRight:
    return LandscapeLeft;
于 2017-11-04T01:24:01.320 回答