【OC】UIImagePickerController相關設置與問題

用戶選擇頭像功能是最常見的調用相機相冊場景,下面就一這一場景為例簡單介紹一下UIImagePickerController的使用蜻懦。

一、 相關方法和屬性詳解:

1、

 + (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType;

用于判斷設備是否支持某一數據源弄跌。UIImagePickerControllerSourceType是系統(tǒng)枚舉值:

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表示靜態(tài)圖片尝苇,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系統(tǒng)中為了更好的進行類型標識淳玩,而提供的一套共用的規(guī)范,也就是“Uniform Type Identifier”非竿,一般稱為“統(tǒng)一類型標識符”,簡稱為“UTI”蜕着。這兩個常量是使用UTI定義的常量,表示"public.image","public.movie"汽馋∥甓可以查看UTCoreTypes.h 文件, 具體可以自行百度一下UTI-iOS圈盔。(主要是碼農我也了解的不多??····)
3、

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

用于判斷設備是否支持前置攝像頭/后置攝像頭悄雅。UIImagePickerControllerCameraDevice是系統(tǒng)枚舉值:

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時萝快,只要你選中了圖片不會出現(xiàn)上圖中界面而知直接會調用代理方法锻霎,即無法查看大圖及編輯。


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); //編程方式拍照昂勒,在該方法執(zhí)行結束會直接調用代理方法
- (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;// 當點擊原生界面中的取消按鈕后會執(zhí)行此代理方法

值得注意的是picker不能關閉自己所以一般要在這兩個代理方法內執(zhí)行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對象

關于圖片和視頻的保存到相簿奕谭,系統(tǒng)有幾個擴展方法:

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(@"保存照片過程中發(fā)生錯誤难捌,錯誤信息:%@",error.localizedDescription);
    }else{
        NSLog(@"照片保存成功.");
    }
}
// 視頻保存到相簿的回調
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (error) {
        NSLog(@"保存視頻過程中發(fā)生錯誤,錯誤信息:%@",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后會發(fā)現(xiàn)所有控件上名稱都是英文的合蔽,若想改為中文有很簡單的一種方法:PROJECT --> Info --> Localizations 然后添加簡體中文即可击敌。


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市拴事,隨后出現(xiàn)的幾起案子沃斤,更是在濱河造成了極大的恐慌,老刑警劉巖刃宵,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衡瓶,死亡現(xiàn)場離奇詭異,居然都是意外死亡牲证,警方通過查閱死者的電腦和手機哮针,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人十厢,你說我怎么就攤上這事等太。” “怎么了蛮放?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵澈驼,是天一觀的道長。 經常有香客問我筛武,道長缝其,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任徘六,我火速辦了婚禮内边,結果婚禮上,老公的妹妹穿的比我還像新娘待锈。我一直安慰自己漠其,他們只是感情好,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布竿音。 她就那樣靜靜地躺著和屎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪春瞬。 梳的紋絲不亂的頭發(fā)上柴信,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音宽气,去河邊找鬼随常。 笑死,一個胖子當著我的面吹牛萄涯,可吹牛的內容都是我干的绪氛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼涝影,長吁一口氣:“原來是場噩夢啊……” “哼枣察!你這毒婦竟也來了?” 一聲冷哼從身側響起燃逻,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤序目,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后唆樊,有當地人在樹林里發(fā)現(xiàn)了一具尸體宛琅,經...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年逗旁,在試婚紗的時候發(fā)現(xiàn)自己被綠了嘿辟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舆瘪。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖红伦,靈堂內的尸體忽然破棺而出英古,到底是詐尸還是另有隱情,我是刑警寧澤昙读,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布召调,位于F島的核電站,受9級特大地震影響蛮浑,放射性物質發(fā)生泄漏唠叛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一沮稚、第九天 我趴在偏房一處隱蔽的房頂上張望艺沼。 院中可真熱鬧,春花似錦蕴掏、人聲如沸障般。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挽荡。三九已至,卻和暖如春即供,著一層夾襖步出監(jiān)牢的瞬間定拟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工募狂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留办素,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓祸穷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親勺三。 傳聞我的和親對象是個殘疾皇子雷滚,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內容

  • 因為要結局swift3.0中引用snapKit的問題,看到一篇介紹Xcode8,swift3變化的文章,覺得很詳細...
    uniapp閱讀 4,416評論 0 12
  • UIImagePickerController是iOS系統(tǒng)提供的和系統(tǒng)的相冊和相機交互的一個類,可以用來獲取相冊的...
    pican閱讀 24,090評論 3 29
  • ? 慢下來是一種美學÷鸺幔——題記 看《朗讀者》的時候祈远,心里會有一種感覺:嘉賓們讀的這篇文寫得好美。于是總油然而生出一...
    蘇靜安閱讀 227評論 2 2
  • 看了大冰的書商源,這幾天恍然大悟车份,書不是僅此寫寫而已,故事應該是那些感人的歲月留在心底最深處的印記牡彻,我們可以隨...
    秋雨落盡閱讀 183評論 0 0
  • 好好的可以睡懶覺的早上 被我自己做的夢嚇醒 夢見老爸生病 嗚嗚嗚 醒來趕緊查查有沒有這個病 這個病到底怎么樣 還好...
    太陽是我捂熱的閱讀 246評論 0 0