I have been using below code to scale my UIImagePickerController's live preview to fill the entire screen. This worked perfectly till now. Before few days, I installed iOS 10 beta 7 on an iPhone 5 and it doesn't scale anymore. I can see black patch at the bottom of UIImagePickerController's view. Seems like cameraViewTransform
is ignoring the CGAffineTransformMakeScale
and CGAffineTransformMakeTranslation
calls.
This is how I initiate my camera controller. I have set both "allowsEditing" and "showsCameraControls" to 'NO' in order to provide my own custom overlay view.
objImagePickerController =[[UIImagePickerController alloc] init];
objImagePickerController.delegate = self;
objImagePickerController.sourceType =UIImagePickerControllerSourceTypeCamera;
objImagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
objImagePickerController.allowsEditing = NO;
objImagePickerController.showsCameraControls= NO;
This is what I use to scale the camera live preview.
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
float screenHeight= MAX(screenSize.height, screenSize.width);
float screenWidth= MIN(screenSize.height, screenSize.width);
float cameraAspectRatio = 4.0 / 3.0;
float imageWidth = floorf(screenWidth * cameraAspectRatio);
float scale = ceilf((screenHeight / imageWidth) * 10.0) / 10.0;
objImagePickerController.cameraViewTransform= CGAffineTransformMakeScale(scale, scale);
This is how I add the camera view as a subview instead of traditional modal presentation method, to suit my own requirements.
[[[UIApplication sharedApplication] keyWindow]addSubview:objImagePickerController.view];
screenshot from iPhone 5s running on iOS 10 beta 8
screenshot from iPhone 5s running on iOS 8.2
As noticeable from the above screenshots, the cameraViewTransform
doesn't respect the CGAffineTransformMakeScale
in iOS 10 beta.
Did anybody else face this issue? This is a really weird behavior appearing in iOS 10 beta OS. I am unable to find a workaround for this. Please advise.
NOTE:: objImagePickerController is an instance of UIImagePickerController.
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.
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