出于某种原因,当我将手机设置为横向模式时,相机预览是颠倒的(水平翻转)。我正在使用 Xamarin 移植的示例项目;AVCam条码。
我最终通过在横向使用 GeometryFlipped 提出了一个半完整的修复。但是,现在绘制的条形码在横向模式下没有绘制在正确的位置。
- 这是设备/操作系统问题还是示例不完整?
纠正此问题的推荐方法是什么?
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 ();
}
}