UIImagePickerController剖析

UIImagePickerController簡單剖析

  1. 個人github
  2. CDSN博客首頁

概述

UIImagePickerController是蘋果官方提供的一套相機、相冊處理的方式。

使用UIImagePickerController你可以調用相機拍攝照片視頻、調用相冊功能。

下面詳細介紹一下其相關的屬性以及API,其中已經遺棄(DEPRECATED)的屬性和方法將不再贅述

相關屬性介紹

1.@property(nonatomic) UIImagePickerControllerSourceType sourceType; // default value is UIImagePickerControllerSourceTypePhotoLibrary.

資源類型,決定相機啓用以後要跳轉到哪個界面(相機拍照、照片圖庫、相冊)

如下幾種值

typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) {
    UIImagePickerControllerSourceTypePhotoLibrary,    //照片圖庫
    UIImagePickerControllerSourceTypeCamera,          //相機
    UIImagePickerControllerSourceTypeSavedPhotosAlbum //相冊
}

2.@property(nonatomic,copy) NSArray<NSString *> *mediaTypes;//默認值是 @[(NSString *)kUTTypeImage].

媒體類型,在相冊模式的時候可以做一些篩選,篩選圖片、視頻、livephoto等各種不同類型的媒體。詳細可設置參數見MobileCoreServices.framework<MobileCoreServices/UTCoreTypes.h>

3.@property(nonatomic) BOOL allowsImageEditing

拍照結束後的是否允許編輯

4.@property(nonatomic) NSTimeInterval videoMaximumDuration

拍攝視頻時的最大拍攝時間

5.@property(nonatomic) UIImagePickerControllerQualityType videoQuality

拍攝視頻的質量

有如下幾種值

typedef NS_ENUM(NSInteger, UIImagePickerControllerQualityType) {
    UIImagePickerControllerQualityTypeHigh = 0,       //最高質量
    UIImagePickerControllerQualityTypeMedium = 1,     //中質量,適合用WIFI傳輸
    UIImagePickerControllerQualityTypeLow = 2,        //低質量,可以用手機網絡傳輸
    UIImagePickerControllerQualityType640x480 = 3,    // VGA質量  640x480 
    UIImagePickerControllerQualityTypeIFrame1280x720 = 4,
    UIImagePickerControllerQualityTypeIFrame960x540 = 5,
}

6.@property(nonatomic) BOOL showsCameraControls

是否顯示系統默認相機UI界面(包括拍攝按鈕、前後攝像頭切換、閃光燈開關),默認爲YES(顯示系統默認UI),如果你需要自定義該界面,則需要隱藏該UI,設置自定義的UI給cameraOverlayView

7.@property(nullable, nonatomic,strong) __kindof UIView *cameraOverlayView

自定義相機遮蓋層,可以自定義拍照框、拍照按鈕、閃關燈、切換前後攝像頭等UI,設置該屬性是,同事需要將屬性showsCameraControls設置爲NO

8.@property(nonatomic) CGAffineTransform cameraViewTransform

設置相機界面旋轉

9.@property(nonatomic) UIImagePickerControllerCameraCaptureMode cameraCaptureMode

拍攝模式(拍攝照片或者拍攝視頻)

下面兩種值

typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraCaptureMode) {
    UIImagePickerControllerCameraCaptureModePhoto, //拍攝照片
    UIImagePickerControllerCameraCaptureModeVideo  //拍攝視頻
}

10.@property(nonatomic) UIImagePickerControllerCameraDevice cameraDevice

設置使用哪個硬件設備,前置攝像頭或者後置攝像頭

如下兩種可選值

typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraDevice) {
    UIImagePickerControllerCameraDeviceRear,  //後置攝像頭
    UIImagePickerControllerCameraDeviceFront  //前置攝像頭
}

11.@property(nonatomic) UIImagePickerControllerCameraFlashMode cameraFlashMode

UIImagePickerControllerCameraFlashMode 閃光燈模式

關閉、自動、打開

如下兩種可選值

typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraFlashMode) {
    UIImagePickerControllerCameraFlashModeOff  = -1, //關閉
    UIImagePickerControllerCameraFlashModeAuto = 0,  //自動
    UIImagePickerControllerCameraFlashModeOn   = 1   //打開
}

相關API方法介紹

1.- (void)takePicture

調用拍攝功能,即相機快門按鈕所擁有的事件

2.- (BOOL)startVideoCapture

開始拍攝視頻

3.- (void)stopVideoCapture

結束拍攝視頻

UIImagePickerControllerDelegate代理方法介紹

1.- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info

拍攝(照片、視頻)、相機選取(照片、視頻)結束之後的回調。

info裏面的具體參數如下:

  • [info objectForKey:UIImagePickerControllerOriginalImage];
    照片的原圖
  • [info objectForKey:UIImagePickerControllerEditedImage];
    裁剪後的圖
  • [info objectForKey:UIImagePickerControllerCropRect];
    圖片裁剪後,剩下的圖
  • [info objectForKey:UIImagePickerControllerMediaURL]
    圖片在相冊中的url
  • [info objectForKey:UIImagePickerControllerMediaMetadata];
    獲取圖片的metadata數據信息

可根據picker.sourceType來判斷是相機拍攝之後的結果還是照片圖庫選擇之後的結果,如果是照片圖庫的話,根據info裏面的參數來判斷是否是圖片還是視頻;如果是相機的話,再根據picker.cameraCaptureMode來判斷拍攝的是圖片還是視頻,區別處理info信息,具體代碼如下

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info; {


    if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) {
        if ([info valueForKey:UIImagePickerControllerOriginalImage]) {
            UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage]; //原始圖片
            //處理圖片信息`info` ...

        }else{
              //處理視頻信息 `info` ...
              NSLog(@"視頻URL是:%@",[info valueForKey:UIImagePickerControllerMediaURL]);
        }
    }else{
        if (picker.cameraCaptureMode == UIImagePickerControllerCameraCaptureModeVideo) {
              //處理視頻信息 `info`
              NSLog(@"視頻URL是:%@",[info valueForKey:UIImagePickerControllerMediaURL]);
        }else{
            UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage]; //原始圖片
              //處理圖片信息`info`   ...
        }
    }


    NSLog(@"%@",info.description);
    [picker dismissViewControllerAnimated:YES completion:nil];
}

PS:如果只是單單的拍照或者拍視頻的話,上面的判斷皆可以修改爲你自己需要的就行

2.- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker

相機界面點擊取消按鈕的回調

裏面寫上如下代碼即可退出相機界面

[imagePicker dismissViewControllerAnimated:YES completion:nil];

相冊存儲相關API

1.UIKIT_EXTERN void UIImageWriteToSavedPhotosAlbum(UIImage *image, __nullable id completionTarget, __nullable SEL completionSelector, void * __nullable contextInfo)

將圖片保存到相冊

簡單的使用:

- (void)saveImageToAlbum:(UIImage *)image {

    UIImageWriteToSavedPhotosAlbum(image, self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), nil);
}

//保存照片成功後的回調
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error
  contextInfo:(void *)contextInfo {

    if (!error) {
        NSLog(@"保存圖片到相冊成功");
    }else {
        NSLog(@"保存圖片到相冊發生錯誤,錯誤信息%@",error);
    }
}

2.UIKIT_EXTERN void UISaveVideoAtPathToSavedPhotosAlbum(NSString *videoPath, __nullable id completionTarget, __nullable SEL completionSelector, void * __nullable contextInfo)

將視頻保存到相冊

簡單的使用:

- (void)saveVideoToAlbum:(NSString *)videoFilePath {

    UISaveVideoAtPathToSavedPhotosAlbum(videoFilePath, self, @selector(videoSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), nil);
}

- (void)videoSavedToPhotosAlbum:(NSString *)videoPath didFinishSavingWithError:(NSError *)error
  contextInfo:(void *)contextInfo{
    if (!error) {
        NSLog(@"保存視頻到相冊成功");
    }else {
        NSLog(@"保存視頻到相冊發生錯誤,錯誤信息%@",error);
    }
}

簡單的使用代碼如下:

 - (void)showCamera {
     UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
     imagePicker.delegate = (id)shareInstance;  
     imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;

    //是否允許編輯照片
    [imagePicker setAllowsEditing:YES];

    //是否顯示默認相機UI
    [imagePicker setShowsCameraControls:YES];
    [imagePicker setCameraDevice:UIImagePickerControllerCameraDeviceFront];
    [imagePicker setCameraFlashMode:UIImagePickerControllerCameraFlashModeAuto];

    //設置媒體類型
    [self.imagePicker setMediaTypes:@[(NSString *)kUTTypeImage]];

    //設置拍攝模式 (拍攝照片或者視頻)
    [self.imagePicker setCameraCaptureMode:UIImagePickerControllerCameraCaptureModePhoto];

     //[self presentViewController:imagePicker animated:YES completion:NULL];
     //需要請求權限,所以上一行行代碼替換爲:
     [self showImagePicker];
 }

PS:需要注意一點,在使用之前要向設備請求相機、相冊權限,所以不能直接present,需要加上下面代碼來請求權限

 - (void) showImagePicker {

    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];

    switch (authStatus) {
        case AVAuthorizationStatusNotDetermined:{
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted){
                 if(granted){
                     [self presentViewController:imagePicker animated:YES completion:NULL];
                 }else{
                     [self showAlert:@"媒體(相機、相冊)訪問未授權"];
                     return;
                 }
             }];
        }
            break;

        case AVAuthorizationStatusAuthorized:
            [self presentViewController:imagePicker animated:YES completion:NULL];
            break;
        default:
            [self showAlert:@"請先在系統設置中對該應用開啓相機、相冊訪問權限"];
            break;
    }
}

PS:還需要注意一點,在使用之前在info.plist中添加相機請求的相關參數,xml代碼如下
要使用設備相機拍照先要對應用開啓相機、相冊的訪問權限,如果需要拍攝視頻還需要開啓麥克風訪問權限。否則會直接crash。

xml代碼如下

<key>NSPhotoLibraryUsageDescription</key>
    <string>App需要您的同意,才能訪問相冊</string>
<key>NSCameraUsageDescription</key>
    <string>App需要您的同意,才能訪問相機</string>
<key>NSMicrophoneUsageDescription</key>
    <string>App需要您的同意,才能訪問麥克風</string>

直接將上述xml複製粘貼到info.plist文件中即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章