如何让UIImagePicker相机的自定义覆盖在iOS 7中全屏?
我感兴趣的是使用UIImagePickerController
自定义覆盖的摄像头控件,采取整个屏幕,非常类似于默认的相机应用程序切换到videofunction时所做的。
我在这里引用了几个关于这个主题的问题,特别是这个,以及Apple如何使用UIImagePickerController自定义覆盖的例子 ,但是没有一个能够产生成功的全屏结果IOS 7。
到目前为止,这是用户界面看起来像自定义覆盖(没有任何button):
请注意,屏幕底部有一个黑色条。 我注意到,如果将cameraAspectRatio
更改为1,我可以将黑色条删除,但是这会使相机变焦变形,因为它会放大视图。 有没有办法让全屏幕变形太多(我明白,一小部分是必要的),也删除黑条?
这是我的代码,configuration自定义覆盖:
{ self.imagePickerController.showsCameraControls = NO; [[NSBundle mainBundle] loadNibNamed:@"overlayView" owner:self options:nil]; self.overlayView.frame = self.imagePickerController.cameraOverlayView.frame; self.imagePickerController.cameraOverlayView = self.overlayView; self.overlayView = nil; // Device's screen size (ignoring rotation intentionally): CGSize screenSize = [[UIScreen mainScreen] bounds].size; float cameraAspectRatio = 4.0 / 3.0; //! Note: 4.0 and 4.0 works float imageWidth = floorf(screenSize.width * cameraAspectRatio); float scale = ceilf((screenSize.height / imageWidth) * 10.0) / 10.0; self.imagePickerController.cameraViewTransform = CGAffineTransformMakeScale(scale, scale); }
更新:
我注意到的一个额外的问题是,相机预览中显示的图片总是较小,并且比当方法[self.imagePickerController takePicture]
时保存的图片更less的细节。 为了显示:
这是键盘在相机预览中的样子,下面是黑条(对不起,它有点不稳固):
但是,请注意,预览面板中实际捕获的图像具有更多的细节,如图所示,尤其是在顶部以及左侧和右侧。
我的问题是,如何能够设置我的相机预览,以便用户在预览中看到的图像完全是它将捕捉的图像,并可以在之后显示给他们? 谢谢!
更新2
这是viewDidLoad
中设置相机控件的完整代码。
- (void)viewDidLoad { [super viewDidLoad]; //Appearance configuration self.navigationItem.hidesBackButton = YES; //UIImagePickerController initialization and setup self.imagePickerController = [[UIImagePickerController alloc] init]; self.imagePickerController.delegate = self; self.imagePickerController.allowsEditing = NO; if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){ self.imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera; //if there is a camera avaliable } else { self.imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;//otherwise go to the folder } self.imagePickerController.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeImage, nil]; if (self.imagePickerController.sourceType == UIImagePickerControllerSourceTypeCamera) { self.imagePickerController.showsCameraControls = NO; [[NSBundle mainBundle] loadNibNamed:@"overlayView" owner:self options:nil]; self.overlayView.frame = self.imagePickerController.cameraOverlayView.frame; self.imagePickerController.cameraOverlayView = self.overlayView; self.overlayView = nil; // Device's screen size (ignoring rotation intentionally): CGSize screenSize = [[UIScreen mainScreen] bounds].size; int heightOffset = 0; if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { heightOffset = 120; //whole screen :) } float cameraAspectRatio = 4.0 / 3.0; //! Note: 4.0 and 4.0 works float imageWidth = floorf(screenSize.width * cameraAspectRatio); float scale = ceilf(((screenSize.height + heightOffset) / imageWidth) * 10.0) / 10.0; self.imagePickerController.cameraViewTransform = CGAffineTransformMakeScale(scale, scale); } }
而在viewWillAppear
,我称之为图像select器视图:
BOOL modalPresent = (BOOL)(self.presentedViewController); //Present the Camera UIImagePicker if no image is taken if (!appDelegate.imageStorageDictionary[@"picture1"]){ if (modalPresent == NO){ //checks if the UIImagePickerController is modally active [self presentViewController:self.imagePickerController animated:NO completion:nil]; } }
经过多次尝试,这对我来说很有帮助,非常感谢别人的build议。 以下事实对于了解和牢记非常有帮助:
相机的分辨率是426 * 320 。 为了将相机预览的高度拉伸到手机的屏幕高度568,使用CGAffineTransformScale
时需要乘以1.3333。
请注意,以下是基于iPhone 5的屏幕分辨率的各种数字硬编码。 通过使用诸如screen.height,screen.width和其他variables之类的对象,可以改进它们,使其适用于iPhone 4 / 4s尺寸。
self.imagePickerController.showsCameraControls = NO; [[NSBundle mainBundle] loadNibNamed:@"overlayView" owner:self options:nil]; self.overlayView.frame = self.imagePickerController.cameraOverlayView.frame; self.imagePickerController.cameraOverlayView = self.overlayView; self.overlayView = nil; //For iphone 5+ //Camera is 426 * 320. Screen height is 568. Multiply by 1.333 in 5 inch to fill vertical CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 71.0); //This slots the preview exactly in the middle of the screen by moving it down 71 points self.imagePickerController.cameraViewTransform = translate; CGAffineTransform scale = CGAffineTransformScale(translate, 1.333333, 1.333333); self.imagePickerController.cameraViewTransform = scale;
在Swift中
var picker: UIImagePickerController = UIImagePickerController(); picker.sourceType = UIImagePickerControllerSourceType.Camera; picker.showsCameraControls = false; var screenBounds: CGSize = UIScreen.mainScreen().bounds.size; var scale = screenBounds.height / screenBounds.width; picker.cameraViewTransform = CGAffineTransformScale(picker.cameraViewTransform, scale, scale);
确保你在iOS7中占用了20px的状态栏变化。 如果你正面临一个20px的黑屏在屏幕底部,那么这将是你的问题。 您可以通过其中一个预处理器检查应用程序是否在ios7中运行
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
你可以对你的代码进行如下修改,看看是否有效
{ self.imagePickerController.showsCameraControls = NO; [[NSBundle mainBundle] loadNibNamed:@"overlayView" owner:self options:nil]; self.overlayView.frame = self.imagePickerController.cameraOverlayView.frame; self.imagePickerController.cameraOverlayView = self.overlayView; self.overlayView = nil; // Device's screen size (ignoring rotation intentionally): CGSize screenSize = [[UIScreen mainScreen] bounds].size; int heightOffset = 0; if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { heightOffset = 20; } float cameraAspectRatio = 4.0 / 3.0; //! Note: 4.0 and 4.0 works float imageWidth = floorf(screenSize.width * cameraAspectRatio); float scale = ceilf(((screenSize.height + heightOffset) / imageWidth) * 10.0) / 10.0; self.imagePickerController.cameraViewTransform = CGAffineTransformMakeScale(scale, scale); }
请让我知道,如果它的工作。 我没有编码testing。
由于屏幕纵横比与相机本身的4/3比例不同,因此需要(如您所述)轻微裁剪边缘以使图像伸展到底部。
为了做到这一点,你需要有足够宽的宽度,使高度可以是全屏。 所以,你的图片宽度和高度必须是:
float cameraAspectRatio = 4.0 / 3.0; //! Note: 4.0 and 4.0 works float imageWidth = screenSize.height / cameraAspectRatio;
您也可能希望视图呈现相机图像是延伸到屏幕两侧的宽度。
我不知道你为什么使用屏幕大小。 试试这个简单的代码:
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) { UIImagePickerController *controller = [[UIImagePickerController alloc] init]; controller.sourceType = UIImagePickerControllerSourceTypeCamera; controller.allowsEditing = NO; controller.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: UIImagePickerControllerSourceTypeCamera]; controller.delegate = self; [self presentViewController:controller animated:NO completion:^{}]; }
试试这个代码来维护自定义大小的结果图像。 我通过使用自定义方法得到结果图像作为自定义大小的结果。
首先为UIImageview
创buildIBOutlet
。
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { NSString *mediaType = info[UIImagePickerControllerMediaType]; [self dismissViewControllerAnimated:YES completion:nil]; if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) { OriginalImage=info[UIImagePickerControllerOriginalImage]; image = info[UIImagePickerControllerOriginalImage]; //---------------------------------------- imageview.image = image; //------------- additional method for custom image size self resizeImage]; //----------------------------------------- if (_newMedia) UIImageWriteToSavedPhotosAlbum(image,self,@selector(image:finishedSavingWithError:contextInfo:),nil); } else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) { // Code here to support video if enabled } }
// —-使用自定义方法调整原始图像大小———————-
-(void)resizeImage { UIImage *resizeImage = imageview.image; float width = 320; float height = 320; CGSize newSize = CGSizeMake(320,320); UIGraphicsBeginImageContextWithOptions(newSize,NO,0.0); CGRect rect = CGRectMake(0, 0, width, height); float widthRatio = resizeImage.size.width / width; float heightRatio = resizeImage.size.height / height; float divisor = widthRatio > heightRatio ? widthRatio : heightRatio; width = resizeImage.size.width / divisor; height = resizeImage.size.height / divisor; rect.size.width = width; rect.size.height = height; //indent in case of width or height difference float offset = (width - height) / 2; if (offset > 0) { rect.origin.y = offset; } else { rect.origin.x = -offset; } [resizeImage drawInRect: rect]; UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); imageview.image = smallImage; imageview.contentMode = UIViewContentModeScaleAspectFit; }
为了解决类似的问题,我从故事板实例化了一个ViewController,并使用控制器的视图作为摄像头覆盖。 我不知道这是你在找什么,但我用下面的代码:
UIImagePickerController *globalPicker = [[UIImagePickerController alloc] init]; globalPicker.delegate = self; globalPicker.sourceType = UIImagePickerControllerSourceTypeCamera;controller=[self.storyboard instantiateViewControllerWithIdentifier:@"myVC"]; overlayView = controller.view; UIView *cameraView=[[UIView alloc] initWithFrame:self.view.bounds]; [cameraView addSubview:overlayView]; [globalPicker setCameraOverlayView:cameraView];
试试这个代码,对我来说工作正常
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init]; cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera; cameraUI.showsCameraControls = NO; CGSize screenSize = [[UIScreen mainScreen] bounds].size; float cameraAspectRatio = 4.0 / 3.0; float imageHeight = floorf(screenSize.width * cameraAspectRatio); float scale = screenSize.height / imageHeight; float trans = (screenSize.height - imageHeight)/2; CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, trans); CGAffineTransform final = CGAffineTransformScale(translate, scale, scale); cameraUI.cameraViewTransform = final ; cameraUI.delegate = self; [self presentViewController:cameraUI animated:YES completion:nil];
此代码假定原始相机预览区域的方面是4:3。
有一种更简单的方法来获得覆盖全屏,至less在iOS 9中testing。
let view = ... your overlayView let bounds = UIScreen.mainScreen().bounds view.center = CGPoint(x: bounds.midX, y: bounds.midY) view.bounds = bounds self.imagePicker.cameraOverlayView = view