繁体   English   中英

如何让UIImagePicker相机的自定义叠加在iOS 7中全屏显示?

[英]How to get the custom overlay for UIImagePicker camera to be full screen in iOS 7?

我有兴趣为UIImagePickerController使用自定义叠加层来拍摄整个屏幕的摄像机控件,非常类似于切换到视频功能时默认的Camera应用程序所做的操作。

关于这个主题,我在这里引用了几个问题,特别是这个问题 ,以及关于如何为UIImagePickerController使用自定义叠加层的Apple示例 ,但是它们都没有能够产生成功的全屏结果。 IOS 7。

到目前为止,这是相机UI与自定义叠加层(没有任何按钮)的样子:

在此输入图像描述

请注意,屏幕底部有一个黑条。 我注意到如果我将cameraAspectRatio更改为1,我可以删除黑条,但是这会使相机变焦变形,因为它具有非常放大的视图。 有没有办法让全屏没有太多扭曲变焦(我明白一点点是必要的),还删除黑条?

这是我配置自定义叠加层的代码:

{
        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]时保存的图片。 为了显示:

这是键盘在相机预览中看起来像下面的黑色条(抱歉它有点不稳定):

在此输入图像描述

但请注意,预览面板中的实际捕获图像具有更多详细信息,如此处所示,尤其是朝向顶部,以及左侧和右侧。

在此输入图像描述

我的问题是,如何设置我的相机预览,以便用户在预览中看到的是它将捕获的图像,然后可以显示给他们? 谢谢!

更新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 ,我调用了图像选择器视图:

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

经过多次尝试,这对我有用,非常感谢其他人的建议。 以下事实非常有助于了解并牢记:

相机的分辨率 426320 *。 为了将相机预览的高度拉伸到手机屏幕高度568,使用CGAffineTransformScale时需要乘以因子1.3333。

请注意,下面的内容是基于iPhone 5的分辨率屏幕分辨率使用各种数字进行硬编码的。 它们可以通过使用诸如screen.height,screen.width和其他变量之类的对象来改进,以使其适用于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;

在斯威夫特

 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);

    }

如果有效,请告诉我。 我没有编码进行测试。

由于屏幕宽高比不同于相机本身的4/3比例,因此您需要(如您所述)轻微裁剪边缘以使图像延伸到底部。

为此,您需要使宽度足够宽,以便高度可以是全屏。 因此,您的图像宽度和高度必须为:

float cameraAspectRatio = 4.0 / 3.0; //! Note: 4.0 and 4.0 works
float imageWidth = screenSize.height / cameraAspectRatio;

您还可能希望视图显示相机图像是从屏幕两侧延伸的宽度。

有一种更简单的方法可以在iOS 9中至少测试覆盖全屏。

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

我不知道你为什么使用屏幕尺寸。 试试这个简单的代码:

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创建IBOutlet

-(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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM