UIImagePickerController簡單剖析
概述
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文件中即可。