首页 文章

UIImagePickerController相机预览是横向应用中的肖像

提问于
浏览
43

在我的仅横向iPhone应用程序中,我启动了一个UIImagePickerController来拍摄照片,但是从相机显示的实时图像是纵向的,周围有空白区域 . 图像旋转 .

按下相机按钮后,预览非常混乱,大部分预览关闭屏幕,并且视图未正确对齐 .

Apple承认这是缺陷,并正在努力 .

我的问题是,是否有人有一个解决方法(合法或非法),这将使我现在能够正常工作 . 我不会通过非法修复发布到App Store,但我会有一个更好的用户测试应用程序 - 目前相机在景观中几乎无法使用 .

如果可以的话,我会附上一个简单的测试项目和图像 .

编辑 - 只是为了澄清,我得到的图像是正确的景观 . 我希望相机和预览UI看起来正确!


Camera http://i42.tinypic.com/2zqsbpy.jpg

alt text http://i43.tinypic.com/168zam0.jpg

5 回答

  • 1

    答案比你想象的更荒谬 . 我遇到了同样的问题,并在某个论坛找到了解决方案 . 将拍摄的图像传递到如下方法:

    // 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;
    }
    

    :(

  • 87

    我认为您根本不需要额外的工作来处理imageRotation或EXIF数据 . 图像drawInRect将自动处理 .

    因此,您只需要获得此尺寸或图像并将其重新绘制为新图像,这就足够了 .

  • 1

    我没有't want to rotate the image after capture; I want to have the preview show correctly in landscape mode. So in iOS 6, I allow portrait mode at the application level, but set the app'的根视图控制器属于类 MyNonrotatingNavigationController ,定义如下:

    @implementation MyNonrotatingNavigationController
    
    -(NSUInteger) supportedInterfaceOrientations
    {
        return UIInterfaceOrientationMaskLandscape;
    }
    
    @end
    

    因此,在此导航控制器中显示的所有内容都将处于横向(您可以使用任何视图控制器执行此操作) . 现在,当我需要显示图像选择器时,我将应用程序窗口的根视图控制器替换为支持纵向模式的通用控制器 . 为了防止旧的根视图控制器及其视图解除分配,我保留指向它们的指针,直到我准备将它们放回应用程序窗口 .

    #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;
            });
        }];
    }
    

    有点痛苦,但它确实适用于照片和视频 . 图像选择器的控件以纵向模式显示,但应用程序的其余部分仅为横向 .

  • 0

    我通过使 UIImagePickerController 以全屏模式出现来解决了这个问题,这也是Apple推荐的iPad .

    来自UIImagePickerController documentation

    在iPad上,如果指定源类型为UIImagePickerControllerSourceTypeCamera,则可以模态(全屏)或使用弹出窗口显示图像选择器 . 但是,Apple建议您仅全屏显示相机界面 .

  • 1

    您需要将自定义视图(带有工具栏和 Headers )设置为 cameraOverlayView ,您还需要将 allowsEditingshowsCameraControls 设置为 NO ,因为这会隐藏标准控件和预览 . 那个's what I'已经在我正在制作的app中找到了(我认为我需要选择器是纵向的,但如果用户将他的设备旋转到横向,我需要它来应用一些ui更改) .
    如果需要,可以提供代码 .

    附:我的代码中仍然存在一些错误,但我正在努力:)

相关问题