iphone - plus - La vista previa de la cámara UIImagePickerController es un retrato en la aplicación horizontal
modo retrato iphone 8 normal (5)
La respuesta es más ridícula de lo que piensas. Tuve el mismo problema y encontré una solución en algún foro. Pase su imagen tomada en un método como este:
// Code from: http://discussions.apple.com/thread.jspa?messageID=7949889
- (UIImage *)scaleAndRotateImage:(UIImage *)image {
int kMaxResolution = 640; // Or whatever
CGImageRef imgRef = image.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
if (width > kMaxResolution || height > kMaxResolution) {
CGFloat ratio = width/height;
if (ratio > 1) {
bounds.size.width = kMaxResolution;
bounds.size.height = roundf(bounds.size.width / ratio);
}
else {
bounds.size.height = kMaxResolution;
bounds.size.width = roundf(bounds.size.height * ratio);
}
}
CGFloat scaleRatio = bounds.size.width / width;
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = image.imageOrientation;
switch(orient) {
case UIImageOrientationUp: //EXIF = 1
transform = CGAffineTransformIdentity;
break;
case UIImageOrientationUpMirrored: //EXIF = 2
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
break;
case UIImageOrientationDown: //EXIF = 3
transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationDownMirrored: //EXIF = 4
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
break;
case UIImageOrientationLeftMirrored: //EXIF = 5
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationLeft: //EXIF = 6
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationRightMirrored: //EXIF = 7
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
case UIImageOrientationRight: //EXIF = 8
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
default:
[NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
}
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
CGContextScaleCTM(context, -scaleRatio, scaleRatio);
CGContextTranslateCTM(context, -height, 0);
}
else {
CGContextScaleCTM(context, scaleRatio, -scaleRatio);
CGContextTranslateCTM(context, 0, -height);
}
CGContextConcatCTM(context, transform);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageCopy;
}
:(
En mi aplicación de iPhone solo para el paisaje, lanzo un UIImagePickerController para tomar una foto, pero la imagen en vivo que se muestra desde la cámara está en orientación vertical, con espacio en blanco a su alrededor. La imagen se gira.
Una vez que se presiona el botón de la cámara, la vista previa es muy desordenada, con la mayoría de la vista previa fuera de la pantalla y las vistas no alineadas correctamente.
Apple ha reconocido que esto es un defecto y está trabajando en ello.
Mi pregunta es, ¿alguien tiene una solución alternativa (legal o ilegal) que me permita hacer que esto funcione ahora? No lanzaría a la tienda de aplicaciones con una solución ilegal, pero tendría una aplicación mucho mejor para las pruebas de usuario: actualmente la cámara es prácticamente inutilizable en el paisaje.
Adjuntaré un proyecto de prueba simple e imágenes si puedo.
Editar - solo para aclarar, la imagen que obtengo es correctamente horizontal. ¡Quiero que la cámara y las UI de vista previa se vean bien!
No creo que necesite el trabajo adicional para tratar con imageRotation o los datos EXIF en absoluto. La imagen drawInRect se encargará de eso automáticamente.
Entonces, solo necesitas obtener este tamaño o la imagen y volver a dibujarla en una nueva imagen, eso sería suficiente.
No quiero rotar la imagen después de la captura; Quiero que la vista previa se muestre correctamente en modo horizontal. Entonces, en iOS 6, permito el modo vertical en el nivel de la aplicación, pero configuro el controlador de vista raíz de la aplicación para que sea de clase MyNonrotatingNavigationController
, definido de la siguiente manera:
@implementation MyNonrotatingNavigationController
-(NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
@end
Entonces, todo lo que se muestra dentro de este controlador de navegación estará en orientación horizontal (podría hacerlo con cualquier controlador de vista). Ahora, cuando necesito mostrar un selector de imágenes, reemplazo el controlador de vista raíz de la ventana de la aplicación por uno genérico que admite el modo vertical. Para evitar que el viejo controlador de vista raíz y sus vistas se desasignaran, mantengo los punteros hasta que esté listo para volver a colocarlos en la ventana de la aplicación.
#define APP_DELEGATE ((MyAppDelegate*)[[UIApplication sharedApplication] delegate])
static UIViewController *pickerContainer = nil;
static UIViewController *oldRoot = nil;
static UIView *holdView = nil;
-(void) showPicker
{
...create UIImagePickerController...
oldRoot = APP_DELEGATE.window.rootViewController;
holdView = [[UIView alloc] initWithFrame:APP_DELEGATE.window.bounds];
[holdView addSubview:oldRoot.view];
pickerContainer = [UIViewController new];
pickerContainer.view = [[UIView alloc] initWithFrame:APP_DELEGATE.window.bounds];
APP_DELEGATE.window.rootViewController = pickerContainer;
[pickerContainer presentViewController:picker animated:YES completion:NULL];
}
-(void) imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
[pickerContainer dismissViewControllerAnimated:YES completion:^{
dispatch_async( dispatch_get_main_queue(), ^{
APP_DELEGATE.window.rootViewController = oldRoot;
[APP_DELEGATE.window addSubview:oldRoot.view];
pickerContainer = nil;
oldRoot = nil;
holdView = nil;
});
}];
}
Es un poco doloroso, pero parece funcionar tanto para fotos como para videos. Los controles del selector de imágenes se muestran en modo vertical, pero el resto de la aplicación es solo horizontal.
Tendrá que establecer una vista personalizada (con la barra de herramientas y el título) como cameraOverlayView
, también tendrá que establecer allowsEditing
y showsCameraControls
en NO
porque eso ocultará controles estándar y la vista previa. Eso es lo que he encontrado como necesario en la aplicación que estoy creando (creo que necesito que el selector esté en retratos, pero necesito que aplique algunos cambios en la interfaz de usuario si el usuario gira su dispositivo a horizontal). Se puede proporcionar un código si es necesario.
PD. Todavía hay algunos errores en mi código, pero estoy trabajando en eso :)
UIImagePickerController
este problema al hacer que el UIImagePickerController
apareciera en modo de pantalla completa, que también es lo que recomienda Apple para iPad.
De la documentación de UIImagePickerController
:
En iPad, si especifica un tipo de fuente de UIImagePickerControllerSourceTypeCamera, puede presentar el selector de imágenes modalmente (pantalla completa) o utilizando un popover. Sin embargo, Apple recomienda que presente la interfaz de la cámara solo a pantalla completa.