美文网首页iOS Developer闻道丶iOS(尝鲜版)
【OC】UIImagePickerController相关设置与

【OC】UIImagePickerController相关设置与

作者: 寻形觅影 | 来源:发表于2017-03-28 17:08 被阅读5533次

    用户选择头像功能是最常见的调用相机相册场景,下面就一这一场景为例简单介绍一下UIImagePickerController的使用。

    一、 相关方法和属性详解:

    1、

     + (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType;
    

    用于判断设备是否支持某一数据源。UIImagePickerControllerSourceType是系统枚举值:

    typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) {
        UIImagePickerControllerSourceTypePhotoLibrary,// 图库即相簿
        UIImagePickerControllerSourceTypeCamera,// 相机
        UIImagePickerControllerSourceTypeSavedPhotosAlbum// 相机胶卷
    } __TVOS_PROHIBITED;
    

    2、

    + (nullable NSArray<NSString *> *)availableMediaTypesForSourceType:(UIImagePickerControllerSourceType)sourceType; 
    

    该方法主要用于获得相机模式下支持的媒体类型:sourceType是UIImagePickerControllerSourceTypeCamera时打印数组为:("public.image","public.movie") public.image表示静态图片,public.movie表示视频。当然也可以是图库或者是相机胶卷的,但是结果只有一个("public.image")
    使用:

    for (NSString* mediaType in [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera]) {
            if ([mediaType isEqualToString: (NSString *)kUTTypeImage]) {
                //支持拍照
                break;
            }
            if ([mediaType isEqualToString: (NSString *)kUTTypeMovie]) {
                //支持摄像
                break;
            }
        }
    
    

    从上面的代码可以看到使用了两个常量:kUTTypeImage和kUTTypeMovie 这两个常量。在这里就要提一下UTI:iOS系统中为了更好的进行类型标识,而提供的一套共用的规范,也就是“Uniform Type Identifier”,一般称为“统一类型标识符”,简称为“UTI”。这两个常量是使用UTI定义的常量,表示"public.image","public.movie"。可以查看UTCoreTypes.h 文件, 具体可以自行百度一下UTI-iOS。(主要是码农我也了解的不多😭····)
    3、

    + (BOOL)isCameraDeviceAvailable:(UIImagePickerControllerCameraDevice)cameraDevice                   NS_AVAILABLE_IOS(4_0); 
    

    用于判断设备是否支持前置摄像头/后置摄像头。UIImagePickerControllerCameraDevice是系统枚举值:

    typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraDevice) {
        UIImagePickerControllerCameraDeviceRear,// 后摄像头
        UIImagePickerControllerCameraDeviceFront // 前摄像头
    } __TVOS_PROHIBITED;
    

    4、

    + (BOOL)isFlashAvailableForCameraDevice:(UIImagePickerControllerCameraDevice)cameraDevice           NS_AVAILABLE_IOS(4_0); 
    

    用于判断设备前置摄像头/后置摄像头是否支持闪光灯。
    5、

    + (nullable NSArray<NSNumber *> *)availableCaptureModesForCameraDevice:(UIImagePickerControllerCameraDevice)cameraDevice NS_AVAILABLE_IOS(4_0); 
    

    获得指定摄像头上的可用捕获模式,返回的是NSNumber *类型,捕获模式是枚举类型:

    typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraCaptureMode) {
        UIImagePickerControllerCameraCaptureModePhoto,//拍照模式
        UIImagePickerControllerCameraCaptureModeVideo//视频录制模式 
    } __TVOS_PROHIBITED;
    

    e.g :

    for (NSNumber* captureMode in [UIImagePickerController availableCaptureModesForCameraDevice:(UIImagePickerControllerCameraDeviceRear)]) {
            if ([captureMode integerValue] == UIImagePickerControllerCameraCaptureModePhoto) {
                JRLog(@"拍照模式");
            }
            if ([captureMode integerValue] == UIImagePickerControllerCameraCaptureModeVideo) {
                JRLog(@"视频录制模式 ");
            }
        }
    

    6、一些属性:

    @property(nullable,nonatomic,weak) id <UINavigationControllerDelegate, UIImagePickerControllerDelegate> delegate; // 必须遵循里面的两个代理
    
    @property(nonatomic) UIImagePickerControllerSourceType sourceType; // 指定 ImagePickerController的数据源,默认是UIImagePickerControllerSourceTypePhotoLibrary
    
    @property(nonatomic,copy) NSArray<NSString *> *mediaTypes;// 设置相机模式或者图库、相机胶卷模式下支持的媒体类型,默认是包含kUTTypeImage即("public.image")的数组,所以拍照时可以不用设置;但是当要录像的时候必须设置,可以设置为kUTTypeVideo(视频,但不带声音)或者kUTTypeMovie(视频并带有声音)
    
    @property(nonatomic) BOOL allowsEditing NS_AVAILABLE_IOS(3_1); // 是否允许编辑,默认是NO,关于这里详见(PS.about-1).
    
    @property(nonatomic) NSTimeInterval videoMaximumDuration NS_AVAILABLE_IOS(3_1); //视频最大录制时长,默认为10分钟。video properties apply only if mediaTypes includes kUTTypeMovie-仅适用于如果媒体类型(mediaTypes)包括kUTTypeMovie视频属性。
    
    @property(nonatomic) UIImagePickerControllerQualityType videoQuality NS_AVAILABLE_IOS(3_1);//设置视频的质量,为枚举类型 ,关于这里详见(PS.about-2).
    
    @property(nonatomic) BOOL showsCameraControls NS_AVAILABLE_IOS(3_1); //是否显示摄像头控制面板,默认为YES。 // 只有sourceType 先设置为UIImagePickerControllerSourceTypeCamera的情况下可用,否则会崩溃
    
    @property(nullable, nonatomic,strong) __kindof UIView * cameraOverlayView  NS_AVAILABLE_IOS(3_1); //摄像头上覆盖的视图(浮于UIImagePickerController视图的最上方),可用通过这个视图来自定义拍照或录像界面。值得注意的是当拍照/录像完成后该界面依然存在。
    
    @property(nonatomic) CGAffineTransform cameraViewTransform NS_AVAILABLE_IOS(3_1);   // 设置摄像头拍摄角度的形变,如 cameraPC.cameraViewTransform = CGAffineTransformMakeRotation(M_PI_2);// 平面旋转90度
    
    @property(nonatomic) UIImagePickerControllerCameraCaptureMode cameraCaptureMode NS_AVAILABLE_IOS(4_0); // 设置摄像头捕获模式,默认是UIImagePickerControllerCameraCaptureModePhoto
    
    @property(nonatomic) UIImagePickerControllerCameraDevice      cameraDevice      NS_AVAILABLE_IOS(4_0); // 设置摄像头设备,默认UIImagePickerControllerCameraDeviceRear
    
    @property(nonatomic) UIImagePickerControllerCameraFlashMode   cameraFlashMode   NS_AVAILABLE_IOS(4_0); // 设置闪光灯模式,枚举类型(详见PS.about-3:),默认是UIImagePickerControllerCameraFlashModeAuto. 
    

    PS.about-1:
    一、调用相机时:
    allowsEditing = YES:



    allowsEditing = NO:



    在设置为NO后,拍摄后的图片是不能拖动和缩放的,即不能编辑只能使用原图。
    二、使用图库或相机胶卷时:
    allowsEditing = YES:

    allowsEditing = NO时,只要你选中了图片不会出现上图中界面而知直接会调用代理方法,即无法查看大图及编辑。


    PS.about-2:
    该属性的枚举类型:

    typedef NS_ENUM(NSInteger, UIImagePickerControllerQualityType) {
        UIImagePickerControllerQualityTypeHigh = 0,       //高清质量
        UIImagePickerControllerQualityTypeMedium = 1,     // 中等质量,适合WiFi传输
        UIImagePickerControllerQualityTypeLow = 2,         // 低质量,适合蜂窝网
        UIImagePickerControllerQualityType640x480 NS_ENUM_AVAILABLE_IOS(4_0) = 3,    // VGA质量,一般不常用
        UIImagePickerControllerQualityTypeIFrame1280x720 NS_ENUM_AVAILABLE_IOS(5_0) = 4,
        UIImagePickerControllerQualityTypeIFrame960x540 NS_ENUM_AVAILABLE_IOS(5_0) = 5,
    } __TVOS_PROHIBITED;
    

    该属性默认是 UIImagePickerControllerQualityTypeMedium,如果相机设备不支持调整视频质量将使用默认值。


    PS.about-3:

    typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraFlashMode) {
        UIImagePickerControllerCameraFlashModeOff  = -1,// 闪光灯关闭
        UIImagePickerControllerCameraFlashModeAuto = 0,// 自动
        UIImagePickerControllerCameraFlashModeOn   = 1// 打开
    } __TVOS_PROHIBITED;
    

    7、

    - (void)takePicture NS_AVAILABLE_IOS(3_1); //编程方式拍照,在该方法执行结束会直接调用代理方法
    - (BOOL)startVideoCapture NS_AVAILABLE_IOS(4_0);//编程方式开始录制视频
    - (void)stopVideoCapture  NS_AVAILABLE_IOS(4_0);//编程方式停止录制视频
    
    二、代理方法及常见内部操作
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info; // 当拍照/录像完成或选择图片完成后都会走此代理方法
    
    - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;// 当点击原生界面中的取消按钮后会执行此代理方法
    

    值得注意的是picker不能关闭自己所以一般要在这两个代理方法内执行dismiss方法!

    对于录制好的视频或者照片的一些操作都在- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info内进行一般就是照片和视频的存储问题。
    info携带信息的key如下所示:

    UIKIT_EXTERN NSString *const UIImagePickerControllerMediaType __TVOS_PROHIBITED; // an NSString (UTI, i.e. kUTTypeImage)获取媒体类型信息
    UIKIT_EXTERN NSString *const UIImagePickerControllerOriginalImage __TVOS_PROHIBITED; // a UIImage 获取原始照片
    UIKIT_EXTERN NSString *const UIImagePickerControllerEditedImage __TVOS_PROHIBITED; // a UIImage 获取编辑后的照片
    UIKIT_EXTERN NSString *const UIImagePickerControllerCropRect __TVOS_PROHIBITED; // an NSValue (CGRect) 获得包含编辑界面的剪裁窗的CGRect值(以此尺寸配合原图得到的新图为正方形图,同时该图旋转了90度)
    UIKIT_EXTERN NSString *const UIImagePickerControllerMediaURL __TVOS_PROHIBITED; // an NSURL //获取拍摄后图片或者视频路径(在SourceType为UIImagePickerControllerSourceTypeCamera时可以获取到)
    UIKIT_EXTERN NSString *const UIImagePickerControllerReferenceURL NS_AVAILABLE_IOS(4_1) __TVOS_PROHIBITED; //选取到的图片或者视频所在素材库的URL(在SourceType不为UIImagePickerControllerSourceTypeCamera时可以获取到)
    UIKIT_EXTERN NSString *const UIImagePickerControllerMediaMetadata NS_AVAILABLE_IOS(4_1) __TVOS_PROHIBITED;  // 获取对象的元数据在SourceType为UIImagePickerControllerSourceTypeCamera时可以获取到)
    UIKIT_EXTERN NSString *const UIImagePickerControllerLivePhoto NS_AVAILABLE_IOS(9_1) __TVOS_PROHIBITED;  // a PHLivePhoto,得到LivePhoto对象
    

    关于图片和视频的保存到相簿,系统有几个扩展方法:

    UIKIT_EXTERN void UIImageWriteToSavedPhotosAlbum(UIImage *image, __nullable id completionTarget, __nullable SEL completionSelector, void * __nullable contextInfo) __TVOS_PROHIBITED; 
    //将照片保存到相簿,其回调方法是:
    - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
    
    UIKIT_EXTERN BOOL UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(NSString *videoPath) NS_AVAILABLE_IOS(3_1) __TVOS_PROHIBITED;
    // 是否允许视频保存到相簿
    
    UIKIT_EXTERN void UISaveVideoAtPathToSavedPhotosAlbum(NSString *videoPath, __nullable id completionTarget, __nullable SEL completionSelector, void * __nullable contextInfo) NS_AVAILABLE_IOS(3_1) __TVOS_PROHIBITED;
    // 将视频保存到相簿,其回调方法是:
     - (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
    

    e.g:

    // UIImagePickControllerDelegate
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
    {
    //以下均是在使用摄像头拍照情况下,在使用相册或图库功能时大致相同
        // 获取媒体类型信息
        NSString *mediaType=[info objectForKey:UIImagePickerControllerMediaType];
        if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {//如果是拍照
            UIImage *image;
            //如果允许编辑则获得编辑后的照片,否则获取原始照片
            if (picker.allowsEditing) {
                image=[info objectForKey:UIImagePickerControllerEditedImage];//获取编辑后的照片
            }else{
                image=[info objectForKey:UIImagePickerControllerOriginalImage];//获取原始照片
            }
            /*
            CGRect cropRect = [[info objectForKey:UIImagePickerControllerCropRect] CGRectValue];
            UIImage * cropImage=[info objectForKey:UIImagePickerControllerOriginalImage];
            UIImage *rotatedOriginalImage = [cropImage imageRotatedByDegrees:90.0];
            CGImageRef imageRef = CGImageCreateWithImageInRect(rotatedOriginalImage.CGImage, cropRect);
            UIImage * resultImage = [UIImage imageWithCGImage:imageRef];
            //以此法获得的图片即为编辑后的图片其中-imageRotatedByDegrees: 方法是将图片顺时针转动90度的方法
            */
            UIImageWriteToSavedPhotosAlbum(image, self, @selector(image: didFinishSavingWithError: contextInfo:), nil);// 若保存到相簿后没有其他操作可以:UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
    
        }else if([mediaType isEqualToString:(NSString *)kUTTypeMovie]){//如果是录制视频
            NSURL *url=[info objectForKey:UIImagePickerControllerMediaURL];//视频路径
            NSString *urlStr=[url path];
            if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(urlStr)) {
                //保存视频到相簿,注意也可以使用ALAssetsLibrary来保存
                UISaveVideoAtPathToSavedPhotosAlbum(urlStr, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);//保存视频到相簿
            }
        }
        [picker dismissViewControllerAnimated:YES completion:^{ }];
    }
    
    - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
    {
        [picker dismissViewControllerAnimated:YES completion:^{ }];
    }
    // 照片保存到相簿的回调
    - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
    {
        if (error) {
            NSLog(@"保存照片过程中发生错误,错误信息:%@",error.localizedDescription);
        }else{
            NSLog(@"照片保存成功.");
        }
    }
    // 视频保存到相簿的回调
    - (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
    {
        if (error) {
            NSLog(@"保存视频过程中发生错误,错误信息:%@",error.localizedDescription);
        }else{
            NSLog(@"视频保存成功.");
            //录制完之后可以使用AVPlayer自动播放
            NSURL *url=[NSURL fileURLWithPath:videoPath];
            NSLog(@"视频路径=%@", url);
        }
    }
    
    

    //该方法是UIImage的分类中自定义的方法,其中DegreesToRadians()是一个宏定义:#define DegreesToRadians(x) (M_PI*(x)/180.0)// 将度数转化成弧度
    - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees{
        UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.height, self.size.width)];
        CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
        rotatedViewBox.transform = t;
        CGSize rotatedSize = rotatedViewBox.frame.size;
        UIGraphicsBeginImageContext(rotatedSize);
        CGContextRef bitmap = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
        CGContextRotateCTM(bitmap, DegreesToRadians(degrees));
        CGContextScaleCTM(bitmap, 1.0, -1.0);
        CGContextDrawImage(bitmap, CGRectMake(-self.size.height / 2, -self.size.width / 2, self.size.height, self.size.width), [self CGImage]);
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
    }
    
    三、关于界面的一些问题(会不断添加~)

    1、原生界面中调用起UIImagePickerController后会发现所有控件上名称都是英文的,若想改为中文有很简单的一种方法:PROJECT --> Info --> Localizations 然后添加简体中文即可。


    相关文章

      网友评论

        本文标题:【OC】UIImagePickerController相关设置与

        本文链接:https://www.haomeiwen.com/subject/xmhfottx.html