在iPad上以纵向模式启动图像选择器

时间:2012-07-14 06:56:05

标签: objective-c ios xcode ipad

我使用以下代码在我的iPad应用程序(使用Cocos2D)中启动图像选择器:

UIImagePickerController * imagePickerController = [[UIImagePickerController alloc] init];

if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { 

    imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
    imagePickerController.showsCameraControls = YES;
    imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
    imagePickerController.delegate = self;
    imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
    [self.view addSubview:imagePickerController.view];
    [self presentModalViewController:imagePickerController animated:YES];

}

我希望它一直以纵向模式启动,但它总是这样启动:

http://www.freeimagehosting.net/t/2deet.jpg

图像以纵向显示,图像选择器UI处于横向模式。但是当我拍摄图像时,它会顺时针旋转90度。

我希望图像选择器UI和拍摄的图像都处于纵向模式。我怎样才能解决这个问题 ?

2 个答案:

答案 0 :(得分:0)

您需要做三件事:

  1. 告诉仅提供imagePicker的viewController 支持纵向方向。
  2. 告诉imagePicker不要旋转实时相机Feed。
  3. 取消旋转拍摄的图像。
  4. imagePicker直接接收设备方向更改的通知。为了防止现场摄像机进给与设备一起旋转,您可以通过告知UIDevice在imagePicker通过以下方式生成方向通知后停止接收这些通知:

    while ([currentDevice isGeneratingDeviceOrientationNotifications])
            [currentDevice endGeneratingDeviceOrientationNotifications];
    

    你把它放在一个循环中的原因是因为imagePicker开始生成设备定位通知,然后在它被解除时结束它,使普通设备上的通知计数从1回到1。

    取消imagePicker后,您可以致电:

    while (![currentDevice isGeneratingDeviceOrientationNotifications])
            [currentDevice beginGeneratingDeviceOrientationNotifications];
    

    以便ViewControllers可以继续接收方向更改通知。

    不幸的是,即使关闭此功能后,图像仍然会在拍摄时保存相机的正确图像方向,因此在保存图像或对其执行任何操作之前,您必须删除应用的方向转换手动反击它:

    -(UIImage *)turnMeAround:(UIImage *)image{
        CGAffineTransform transform = CGAffineTransformIdentity;
        CGFloat scale = [[UIScreen mainScreen] scale]; //retina
        CGSize size = CGSizeMake(image.size.width*scale,image.size.height*scale);
        switch (image.imageOrientation) {
            case UIImageOrientationUp:
                return image;
            case UIImageOrientationDown:
                size = CGSizeMake(size.height,size.width);
                transform = CGAffineTransformRotate(transform, M_PI);
                break;
            case UIImageOrientationLeft:
                transform = CGAffineTransformRotate(transform, -M_PI_2);
                break;
            case UIImageOrientationRight:
                transform = CGAffineTransformRotate(transform, M_PI_2);
                break;
        }
        CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), CGImageGetBitmapInfo(image.CGImage));
        CGContextConcatCTM(context, transform);
        CGContextDrawImage(context, CGRectMake(0,0,size.width,size.height), image.CGImage);
        CGImageRef ref = CGBitmapContextCreateImage(context);
        UIImage *upsideRight = [UIImage imageWithCGImage:ref];
        CGContextRelease(context);
        CGImageRelease(ref);
        return upsideRight;
    }
    

答案 1 :(得分:0)

非常感谢所有帮助,但对我有用的是:

所以我发现它是Xcode的Cocos2D模板,这是罪魁祸首。它在RootViewController中生成了以下代码:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

//
// There are 2 ways to support auto-rotation:
//  - The OpenGL / cocos2d way
//     - Faster, but doesn't rotate the UIKit objects
//  - The ViewController way
//    - A bit slower, but the UiKit objects are placed in the right place
//

#if GAME_AUTOROTATION==kGameAutorotationNone
//
// EAGLView won't be autorotated.
// Since this method should return YES in at least 1 orientation, 
// we return YES only in the Portrait orientation
//
return ( interfaceOrientation == UIInterfaceOrientationPortrait );

#elif GAME_AUTOROTATION==kGameAutorotationCCDirector
//
// EAGLView will be rotated by cocos2d
//
// Sample: Autorotate only in landscape mode
//
if( interfaceOrientation == UIInterfaceOrientationLandscapeLeft ) {
    [[CCDirector sharedDirector] setDeviceOrientation: kCCDeviceOrientationLandscapeRight];
} else if( interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
    [[CCDirector sharedDirector] setDeviceOrientation: kCCDeviceOrientationLandscapeLeft];
}

// Since this method should return YES in at least 1 orientation, 
// we return YES only in the Portrait orientation
return ( interfaceOrientation == UIInterfaceOrientationPortrait );

#elif GAME_AUTOROTATION == kGameAutorotationUIViewController
//
// EAGLView will be rotated by the UIViewController
//
// Sample: Autorotate only in landscpe mode
//
// return YES for the supported orientations

return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );

#else
#error Unknown value in GAME_AUTOROTATION

#endif // GAME_AUTOROTATION


// Shold not happen
return NO;
}

在上面的代码中我改变了这个:

return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );

对此:

return ( UIInterfaceOrientationIsPortrait( interfaceOrientation ) );

这就解决了。