2017-11-03 15 views
1

電話機を横向きにすると何らかの理由でカメラのプレビューが上下逆さまになります(水平に反転)。私はXamarinが移植したサンプルプロジェクトを使用しています。 AVCamBarcodeiOS VideoPreview風景が逆さまになっています

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(); 
    } 
} 
+0

'VideoOrientationFor(に何があるか)' –

+0

@LouFrancoは私のポストにそれを追加しました。 – vdidxho

+0

私はこれがクレイジーだと知っていますが、私のアプリの同等のものは、左右が逆転しています(右に戻るとその逆になります)。 –

答えて

1

デバイスとビデオの向きは、景観のために異なる意味を持ちます。

The docs say (for video)

場合は

は、右の一番上の、映像が水平方向に配向されることを示しlandscapeLeft。

場合は

は、左の一番上の、映像が水平方向に配向されることを示しlandscapeRight。

しかしdevice orientation言う:

場合は、デバイスが直立開催されたデバイスと右側にホームボタンで、風景モードである

をlandscapeLeft。

場合は、デバイスが直立開催されたデバイスと左側にあるホームボタンで、風景モードである

をlandscapeRight。

だから、あなたはこれに変更する必要があります:

case UIDeviceOrientation.LandscapeLeft: 
    return LandscapeRight; 
case UIDeviceOrientation.LandscapeRight: 
    return LandscapeLeft; 
+0

私はそれを試してみることを考えましたが、おかげで束@ルーフランコ – vdidxho

関連する問題