iOS:<Photos/Photos.h>獲取相冊視頻以及圖片

因為項目的需求,要捕獲相冊中的視頻與圖片,之前也對之尚未做過什么探討,僅知道iOS8.0后,蘋果推出了新的相冊管理的包,那么正好,現(xiàn)在可以看看這個框架了,也知道AlAssetLibrary,使用的話倒是沒有詳細應(yīng)用過,因此也不與PhotoKit進行對比了。

temp.gif

類的介紹:

//PHCachingImageManager(PHImageManager的抽象) 處理圖像的整個加載過程的緩存要加載大量資源的縮略圖時可以使用該類的startCachingImage...預(yù)先將圖像加載到內(nèi)存中 ,使用時注意size要一致

成員介紹

先挑明自己踩到的坑..

1、 首次調(diào)用相冊權(quán)限的為難:僅會獲取相應(yīng)的權(quán)限提示 而不會響應(yīng)方法
    //每次訪問相冊都會調(diào)用這個handler  檢查改app的授權(quán)情況
    //PHPhotoLibrary 
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        if (status == PHAuthorizationStatusAuthorized) {
          //code
        }
    }];
2、獲取所有圖片(注意不能在膠卷中獲取圖片,因為膠卷中的圖片包含了video的顯示圖)
    [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];//這樣獲取
    也可以使用PHFetchOptions中的謂詞過濾獲取
    PHFetchOptions *fetchResoultOption = [[PHFetchOptions alloc] init];
    fetchResoultOption.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:false]];
    fetchResoultOption.predicate = [NSPredicate predicateWithFormat:@"mediaType = %d",PHAssetMediaTypeImage];
3、使用PHImageManager請求時的回調(diào)同步or異步時、block回調(diào)次數(shù)的問題
4、回調(diào)得出的圖片size的問題: 由3個參數(shù)決定
     在ShowAlbumViewController 中觀察
     在PHImageContentModeAspectFill 下  圖片size 有一個分水嶺  {125,125}   {126,126}
     當imageOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
     時: 設(shè)置size 小于{125,125}時,你得到的圖片size 將會是設(shè)置的1/2
     而在PHImageContentModeAspectFit 分水嶺  {120,120}   {121,121}
5、回調(diào)中info字典key消失的問題:
      簡單地說,就是你如果是自定義的size,且返回的圖片的size小于源圖片的size 那么你將會得不到圖片的相對路徑等部分key
6、顯示的相冊名字不是中文:在info.plist 中設(shè)置
      Localized resources can be mixed   YES
      本地資源的適配
7、This app has crashed because it attempted to access privacy-sensitive data
    without a usage description.  
    The app's Info.plist must contain an NSPhotoLibraryUsageDescription key 
    with a string value explaining to the user how the app uses this data.
    本app因未得到使用說明就直接企圖訪問私人數(shù)據(jù)而導(dǎo)致崩潰。
    app想要訪問這些私人數(shù)據(jù)就得在info.plist增加一個以NSPhotoLibraryUsageDescription為鍵,以字符串為值的鍵值對。=

一、先來一個簡單的練習(xí)吧:獲取本機系統(tǒng)所有的圖片

在collectionView中

- (void)getAllPhotosFromAlbum {//配置簡單 ,但是參數(shù)卻是比價多且
    self.options= [[PHImageRequestOptions alloc] init];//請求選項設(shè)置
    self.options.resizeMode=PHImageRequestOptionsResizeModeExact;
//resizeMode  自定義設(shè)置圖片的大小 枚舉類型*
// PHImageRequestOptionsResizeMode:*
//PHImageRequestOptionsResizeModeNone = 0, //保持原size
//PHImageRequestOptionsResizeModeFast, //高效、但不保證圖片的size為自定義size
//PHImageRequestOptionsResizeModeExact, //嚴格按照自定義size

   self.options.synchronous=YES;   //YES 一定是同步    NO不一定是異步
  imageOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
        /*
     PHImageRequestOptionsResizeModeNone // 不調(diào)整大小
     PHImageRequestOptionsResizeModeFast // 由系統(tǒng)去安排,情況不定:有時你設(shè)置的size比較低,會根據(jù)你設(shè)的size,有時又會比
     PHImageRequestOptionsResizeModeExact// 保證精確到自定義size :此處精確的前提得用PHImageContentModeAspectFill
     */
    
    //simageOptions.version = PHImageRequestOptionsVersionCurrent;//版本 iOS8.0之后出的圖片編輯extension,可以根據(jù)次枚舉獲取原圖或者是經(jīng)編輯過的圖片,
    /*PHImageRequestOptionsVersion:
     PHImageRequestOptionsVersionCurrent = 0, //當前的(編輯過?經(jīng)過編輯的圖:原圖)
     PHImageRequestOptionsVersionUnadjusted, //經(jīng)過編輯的圖
     PHImageRequestOptionsVersionOriginal    //原始圖片
     */
    
    //    imageOptions.networkAccessAllowed = YES;//用于開啟iClould中下載圖片
    //    imageOptions.progressHandler   //iClould下載進度的回調(diào)
    
    imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;//在imageOptions.synchronous = NO的情況下最終決定是否是異步

//容器類
  (PHFetchResult *) self.assets= [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];
    //此處option是對獲取得到對 Collection 的配置  我只是把它設(shè)為nil了 可以這樣使用
   /*
//例如按資源的創(chuàng)建時間進行一個排序
         PHFetchOptions *options = [[PHFetchOptions alloc] init];
//    NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:nil ascending:YES];
         options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]]; 
//其中:key是PHAsset類的屬性   這是一個kvc
         PHFetchResult *assetsFetchResults = [PHAsset fetchAssetsWithOptions:options];
    */
  [self.containView.collectionView reloadData];
}

- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath {
    AlbumCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ALBUMCELLID forIndexPath:indexPath];
//cell.backgroundColor= [UIColor redColor];
    CGSize size =CGSizeMake(50,50);//自定義image size變化情況頗為復(fù)雜 下面由說到

    //返回一個 PHImageRequestID,在異步請求時可以根據(jù)這個ID去取消請求,同步就沒辦法了..
    [[PHImageManager defaultManager] requestImageForAsset:self.assets[indexPath.row] targetSize:size contentMode:PHImageContentModeDefault options:self.options resultHandler:^(UIImage*_Nullable result,NSDictionary*_Nullable info) {
 /*
         最終產(chǎn)生圖片的size是有   imageOptions.resizeMode(即PHImageRequestOptions) 以及 PHImageContentMode  決定的,當然也有我們設(shè)定的size
         優(yōu)先級而言 
         PHImageRequestOptions > PHImageContentMode
         */
        //這個handler 并非在主線程上執(zhí)行,所以如果有UI的更新操作就得手動添加到主線程中
//       dispatch_async(dispatch_get_main_queue(), ^{ //update UI  });

#pragma If -[PHImageRequestOptions isSynchronous] returns NO (or options is nil), resultHandler may be called 1 or more times. .........異步就這個回調(diào)會調(diào)用1或多次....
#pragma If -[PHImageRequestOptions isSynchronous] returns YES, resultHandler will be called exactly once同步就1次.
//一開始本來打算是利用數(shù)據(jù)吧所有的相片先存起來的.但是發(fā)現(xiàn)同步會卡UI  但是異步又會被回調(diào)多次,我的數(shù)組都變成double了...只好把任務(wù)方法方法cellforItem中
    cell.photoImageView.contentMode = UIViewContentModeScaleAspectFit;
    cell.photoImageView.image = result;
}];
  return cell;
}
/*注意這個info字典   有時這個info甚至為null   慎用
     里面的key是比較奇怪的
     盡量不要用里面的key
     因為這個key 會變動: 當我們最終獲取到的圖片的size的高/寬  沒有一個達到能原有的圖片size的高/寬時
     部分key 會消失  如 PHImageFileSandboxExtensionTokenKey , PHImageFileURLKey
     */
    /*
     在PHImageContentModeAspectFill 下  圖片size 有一個分水嶺  {125,125}   {126,126}
     當imageOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
     時: 設(shè)置size 小于{125,125}時,你得到的圖片size 將會是設(shè)置的1/2
     
     而在PHImageContentModeAspectFit 分水嶺  {120,120}   {121,121}   
     至于為什么會這樣???- -   可能蘋果考慮性能吧
     */

注意到上面這個resultHandler,返回一個UIImage,以及一個NSDictionary,圖片就不多說了,關(guān)鍵是這個info實在是詭異...

這就引起了我的關(guān)注:size和key的關(guān)系

圍繞著size的大小這個key竟然是不一樣的............
我把圖也打印出來了// 條件: size = {300,300}


本來是猜測我們設(shè)定的這個size比原圖小的時候,會產(chǎn)生一張新的圖片,而這張圖片本地資源是不存在的,所以少了部分的key,

但是現(xiàn)在就尷尬了,看第二個image的原圖,分明也是比{300,300}小的,為什么也沒了部分key了呢,不太懂....

大家不要誤會,第一張圖片的原圖是肯定大于{300,300} 的,為什么顯示不是{300,300},因為我使用處理圖片的模式為PHImageContentModeAspectFit,所以顯示下來的并非我們{300,300}而是保留原圖的比例,大家可以動手去試一試

而且這個size其實是像素:
CGSizeMake(self.assets[indexPath.row].pixelWidth,self.assets[indexPath.row].pixelHeight);
或者設(shè)定一個肯定比原圖大的size就能獲取到原圖了....當然,后者是不靠譜的...

或許是這個size出的問題吧,會導(dǎo)致如果我要根據(jù)這個PHimageFileKey 獲取本地的圖片的時候就因為某部分的image因為size的原因缺少這個key使得找不到這張圖,使得我app出現(xiàn)bug....不過這個方法真的挺不安全的,建議是把返回的result 那張image 寫進tmp里面 再使用吧。。。。

再者就是異步請求次數(shù)跟size的關(guān)系

當我的self.options.synchronous=NO;//就是一個異步請求的過程(后來發(fā)現(xiàn)其實異步請求并不由options的synchronous屬性決定)
而這個PHImageRequestOptions 可以根據(jù)它的一個屬性deliveryMode 去控制異步請求的次數(shù)
PHImageRequestOptionsDeliveryMode:
PHImageRequestOptionsDeliveryModeOpportunistic//根據(jù)我self.options.synchronous判斷返回結(jié)果是一個抑或多個
PHImageRequestOptionsDeliveryModeHighQualityFormat //制定的同步返回一個結(jié)果,返回的圖片質(zhì)量是比我們設(shè)定的size會好一點(實際上與PHImageRequestOptions的resizeMode枚舉相關(guān))
PHImageRequestOptionsDeliveryModeFastFormat//僅返回一次,效率較高之余獲得的圖質(zhì)量不太好

 我這邊配合的resizeMode模式為強制自定義的圖片大小,即:
self.options.resizeMode=PHImageRequestOptionsResizeModeExact;//嚴格按照自定義圖片大小的加載模式

如果不是這個枚舉的話,返回的PHImageRequestOptionsDeliveryModeOpportunistic第一次返回的縮略圖,以及PHImageRequestOptionsDeliveryModeFastFormat所返回的縮略圖最小默認是{60,60},
PHImageRequestOptionsResizeModeExact則可以隨意設(shè)置

值得注意的是,當我們選擇的是PHImageRequestOptionsDeliveryModeOpportunistic時,返回的次數(shù)是跟size有關(guān)系的,你設(shè)定的的size 太小的話僅會回調(diào)一次,大的話,首次返回的是一個小的縮略圖(這個縮略圖最大是{60,60},具體值根據(jù)比例),二次回調(diào)才會得到我們想要的圖片

總而言之,圖片的真實size跟resizeMode和PHImageRequestOptionsDeliveryMode以及我們設(shè)定的size都有關(guān)聯(lián)吧,具體應(yīng)用的時候就要多試試幾次,觀察自己真實所需吧...

接下來的是我要找的是視頻......問題又出現(xiàn)了,這個PhotoKit有提供查找視頻的方式么...
然后我把這修改了一下。。。改成了找Video 的元數(shù)據(jù)   哈哈哈哈哈哈哈
self.assets= [PHAsset fetchAssetsWithMediaType:**PHAssetMediaTypeVideo** options:nil];

但我好像又踩上了自己挖的坑了...



全是圖片....不,不是這樣的。。。

在回頭看看發(fā)現(xiàn)有PHImageManager 這個單例提供我們3個方法去找得到Vide 我則選取了其中一個通用的方法

PHFetchResult *assetsResult = [PHAssetfetch AssetsWithMediaType:PHAssetMediaType Videooptions:nil];
PHVideoRequestOptions *options2 = [[PHVideoRequestOptions alloc] init];
options2.deliveryMode=PHVideoRequestOptionsDeliveryModeAutomatic;
for(PHAsset *a in assetsResult) {                       
   [[PHImageManager defaultManager] requestAVAssetForVideo:a options:options2 resultHandler:^(AVAsset*_Nullable asset,
    AVAudioMix*_Nullable audioMix,NSDictionary*_Nullable info) {
    NSLog(@"%@",info);
  }];
}

找到你了....

不過你居然在。。。PHImageFileSandboxExtensionTokenKey。。。這個key里面



看來地址是要用要用截取的了,可以直接輸入到finder就能找到這個視頻,但是前面的字符串就得讓我們手動去取其子字符串只需要拿到video的Path就可以了

很不安全,我真的怕這個key突然又因為什么原因而miss掉了........
然后我看了看asset 的類型 發(fā)現(xiàn)它的類型為AVURLAsset,有點意思,看看里面發(fā)現(xiàn)了一個是有個URL屬性的!而且是asset的相對路徑, 好像可以做點什么...

//video路徑獲取
if (asset && [asset isKindOfClass:[AVURLAsset class]] && [NSString stringWithFormat:@"%@",((AVURLAsset *)asset).URL].length > 0) {
  NSString *videoURLStr = [NSString stringWithFormat:@"%@",((AVURLAsset *)asset).URL];
  videoPath = ((AVURLAsset*)asset).URL.path;
}

二、根據(jù)實際需求的部分獲取資源

怎么個實際法呢,有時候你對著一大堆圖片,然后找啊找,調(diào)啊調(diào),還真的不是什么好方法...為什么就不能在我分好的類別中選取呢!!!!

好的,就下來就說這種情況,大家在開頭都一定看到那幅,資源與資源集合的一個關(guān)系圖...

獲取所有用戶自定義的相冊:1\2\3分別是我創(chuàng)建的相冊,以下代碼能捕獲到,自己創(chuàng)建的的相冊的內(nèi)容


捕獲系統(tǒng)相冊中的圖片/video


解釋一下

PHFetchResult*smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];

這個獲取資源集合的方法 需要填寫兩個枚舉的類型,大概翻譯了下,有錯誤的大家可以提一下,我會非常感激的

demo地址
參考文章:
1、照片框架:https://objccn.io/issue-21-4/#PhotoKit-Object-Model%5D(http://objccn.io/issue-21-4/#PhotoKit-Object-Model
2、iOS 開發(fā)之照片框架詳解:http://kayosite.com/ios-development-and-detail-of-photo-framework.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內(nèi)容

  • 一、 PhotoKit的變量: PHAdjustmentData: When a user edits an as...
    漓汐Arthur閱讀 1,706評論 1 3
  • 昨天一天下午還真是個種查,各種搜索,然后各種技術(shù)群,各種問,(沒人鳥我),其實我是有這個能力的,怎么就一上...
    夢隨興飛閱讀 25,127評論 7 18
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,828評論 18 139
  • 在太多的地方搭建過博客了,重csdn到自己免費空間搭建wordpress,其次到基于otcopress在githu...
    好迪閱讀 471評論 0 1
  • 那一次的四目相對 讓我聽到了花開的聲音 如今的我 正坐在沒有你的陌生教室里 憶著你給我的感覺 懷念 只能懷念
    二楠_nnn閱讀 276評論 0 0