UIImagePickerController's cameraViewTransform is ignoring 'scaling' and 'translation' on iOS 10 beta

两盒软妹~` 提交于 2019-11-30 18:43:29

Strangely it only allows us to transform it after the presentation was completed.

Example:

self.presentViewController(
        self.imagePicker,
        animated: true,
        completion: {
            let screenSize = UIScreen.mainScreen().bounds.size
            let ratio: CGFloat = 4.0 / 3.0
            let cameraHeight: CGFloat = screenSize.width * ratio
            let scale: CGFloat = screenSize.height / cameraHeight

            self.imagePicker.cameraViewTransform = CGAffineTransformMakeTranslation(0, (screenSize.height - cameraHeight) / 2.0)
            self.imagePicker.cameraViewTransform = CGAffineTransformScale(self.imagePicker.cameraViewTransform, scale, scale)
        }
    )

This code will transform the camera view to match the screen size.

Note that this is a workaround. It works, but the user will see it resizing upon presentation.

Hans Knöchel

As answered here, this issue has been fixed in iOS 10.2 and you can use the cameraViewTransform property before presenting the camera again.

I've solved by delaying set cameraViewTransform after camera e AVCaptureSessionDidStartRunningNotification is raised:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cameraIsReadyNotification:) name:AVCaptureSessionDidStartRunningNotification object:nil]; 

-

- (void)cameraIsReadyNotification:(NSNotification *)notification  
 {  
          dispatch_async(dispatch_get_main_queue(), ^{  
          float scale = ceilf((screenHeight / imageWidth) * 10.0) / 10.0;

          objImagePickerController.cameraViewTransform=CGAffineTransformMakeScale(scale, scale);
          });  
  }

I had the same problem earlier in IOS 9.3 also. Here is the code i used

//transform values for full screen support
#define CAMERA_TRANSFORM_X 1
#define CAMERA_TRANSFORM_Y 1.12412    

        if (IS_IPAD)
            CGAffineTransformScale(objImagePickerController.cameraViewTransform, CAMERA_TRANSFORM_X,  CAMERA_TRANSFORM_Y);
        else if (IS_IPHONE_5_Land||IS_IPHONE_4_Land||IS_IPHONE_6_Land||IS_IPHONE_6_PLUS_Land)
        {
            objImagePickerController.cameraViewTransform = CGAffineTransformScale(CGAffineTransformIdentity, 2, 2);
        }

Hope this helps

I had the same problem in my augmented reality application and finally solved it by using AVFoundation framework instead of UIImagePickerController. It seems that cameraViewTransform no longer works on iOS 10.

The code below worked for me. Add the function to your UIViewController subclass and call it.

- (BOOL) initCamera {

    AVCaptureSession *captureSesion = [[AVCaptureSession alloc] init];
    if ([captureSesion canSetSessionPreset:AVCaptureSessionPresetHigh]) {
        [captureSesion setSessionPreset:AVCaptureSessionPresetHigh];
    } else {
        return false;
    }
    AVCaptureDevice *camera = nil;
    NSArray<AVCaptureDevice*>* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    // Select back camera
    for (AVCaptureDevice *device in devices) {
        if ([device position]==AVCaptureDevicePositionBack) {
            camera = device;
            break;
        }
    }
    if (camera == nil) {
        // Back camera not found.
        return false;
    }

    AVCaptureStillImageOutput *imageOutput = [[AVCaptureStillImageOutput alloc]init];
    [imageOutput setOutputSettings: @{AVVideoCodecKey: AVVideoCodecJPEG}];
    AVCaptureDeviceInput *deviceInput = [[AVCaptureDeviceInput alloc]initWithDevice:camera error: nil];

    if (![captureSesion canAddInput:deviceInput] || ![captureSesion canAddOutput:imageOutput]) {
        return false;
    }
    [captureSesion addInput:deviceInput];
    [captureSesion addOutput:imageOutput];

    AVCaptureVideoPreviewLayer *layer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:captureSesion];

    // "Aspect Fill" is suitable for fullscreen camera.
    layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    layer.frame = self.view.bounds;
    layer.connection.videoOrientation = AVCaptureVideoOrientationPortrait;

    [self.view.layer addSublayer:layer];
    [captureSesion startRunning];

    return true;
}

The most important thing is to use AVLayerVideoGravityResizeAspectFill. With this configuration, the camera view fills the container view keeping its original aspect ratio.

Don't forget to import the framework:)

#import <AVFoundation/AVFoundation.h>

corrigé dans la version ios 10.2 Issue solved in ios 10.2 version

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!