AVCaptureVideoPreviewLayer smooth orientation rotation

后端 未结 9 901
Happy的楠姐
Happy的楠姐 2021-02-02 16:45

I\'m trying to disable any discernable orientation rotation to an AVCaptureVideoPreviewLayer while still maintaining rotation for any subviews. AVCaptureVideoPreviewLayer does h

相关标签:
9条回答
  • 2021-02-02 16:47

    This is how I do it:

    - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
        if (tookFirstPicture)
            return;
    
        if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
            [previewLayer setOrientation:AVCaptureVideoOrientationPortrait];
        }
        else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
            [previewLayer setOrientation:AVCaptureVideoOrientationLandscapeLeft];
        }
        else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
            [previewLayer setOrientation:AVCaptureVideoOrientationLandscapeRight];
        }
        else {
            [previewLayer setOrientation:AVCaptureVideoOrientationPortraitUpsideDown];
        }
    }
    
    0 讨论(0)
  • 2021-02-02 16:48

    In swift I use:

    override func willAnimateRotationToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
        if !UIDevice.currentDevice().model.contains("Simulator") {
            if (toInterfaceOrientation == .Portrait) {
                prevLayer?.transform = CATransform3DMakeRotation(0, 0, 0, 1)
            } else if (toInterfaceOrientation == .LandscapeLeft) {
                prevLayer?.transform = CATransform3DMakeRotation(CGFloat(M_PI)/2, 0, 0, 1)
            } else if (toInterfaceOrientation == .LandscapeRight) {
                prevLayer?.transform = CATransform3DMakeRotation(-CGFloat(M_PI)/2, 0, 0, 1)
            }
            prevLayer?.frame = self.scanView.frame
        }
    }
    
    0 讨论(0)
  • 2021-02-02 16:48

    Since AVCaptureVideoPreviewLayer is a CALayer, then any changes will be animated, http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/AnimatingLayers.html. To stop the animation just [previewLayer removeAllAnimations].

    0 讨论(0)
  • 2021-02-02 16:50

    I was able to accomplish this with the following code:

    Set up when you need the camera:

    preview = [[self videoPreviewWithFrame:CGRectMake(0, 0, 320, 480)] retain];
    [self.view addSubview:preview];
    

    The videoPreviewWithFrame function.

    - (UIView *) videoPreviewWithFrame:(CGRect) frame {
      AVCaptureVideoPreviewLayer *tempPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]];
      [tempPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
      tempPreviewLayer.frame = frame;
    
      UIView* tempView = [[UIView alloc] init];
      [tempView.layer addSublayer:tempPreviewLayer];
      tempView.frame = frame;
    
      [tempPreviewLayer autorelease];
      [tempView autorelease];
      return tempView;
    }
    
    0 讨论(0)
  • 2021-02-02 16:56

    Using an affine transform on the view containing the preview layer creates a smooth transition:

    - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
        if (cameraPreview) {
            if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
                cameraPreview.transform = CGAffineTransformMakeRotation(0);
            } else if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) {
                cameraPreview.transform = CGAffineTransformMakeRotation(M_PI/2);
            } else if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) {
                cameraPreview.transform = CGAffineTransformMakeRotation(-M_PI/2);
            }
            cameraPreview.frame = self.view.bounds;
        }
    }
    

    The willAnimateRotationToInterfaceOrientation function is called within the rotation animation block so changing properties here will animate along with the rest of the rotation animations. This function has been phased out in iOS 6 and replaced with new methods to handle device rotation, so this works for now, but isn't the best solution.

    0 讨论(0)
  • 2021-02-02 16:59

    You should use CATransform3DMakeRotation which is meant for Layers, like it has been mentioned on the comments:

    For instance:

    float degreesToRotate = 90.0; //Degrees you want to rotate
    self.previewLayer.transform = CATransform3DMakeRotation(degreesToRotate / 180.0 * M_PI, 0.0, 0.0, 1.0);
    

    In my case, being "self.previewLayer" the layer to rotate. Have in mind that you should clip it to it's container view's bounds afterwards:

    self.previewLayer.frame = self.view.bounds;
    

    . . .

    EDIT: If you are going to rotate as a result of the device being rotated (willAnimateRotationToInterfaceOrientation) you should make the transformation like this:

    [CATransaction begin];
        [CATransaction setAnimationDuration:duration];
        [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        //**Perform Transformation here**
        [CATransaction commit];
    

    This way, the layer will rotate as the view does.

    0 讨论(0)
提交回复
热议问题