国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > iOS > 正文

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

2019-11-06 09:39:26
字體:
供稿:網(wǎng)友

轉(zhuǎn)自:http://www.jianshu.com/p/ea0274a33209

因?yàn)轫?xiàng)目的需求,要捕獲相冊(cè)中的視頻與圖片,之前也對(duì)之尚未做過什么探討,僅知道iOS8.0后,蘋果推出了新的相冊(cè)管理的包,那么正好,現(xiàn)在可以看看這個(gè)框架了,也知道AlAssetLibrary,使用的話倒是沒有詳細(xì)應(yīng)用過,因此也不與PhotoKit進(jìn)行對(duì)比了。先放個(gè)git:https://github.com/wizetLee/TestPhotoKit

類的介紹:

//PHAsset 用戶照片庫中一個(gè)單獨(dú)的資源,簡(jiǎn)單而言就是單張圖片的元數(shù)據(jù)吧//PHAsset 組合而成PHAssetCollection(PHCollection)一個(gè)單獨(dú)的資源集合(PHAssetCollection)可以是照片庫中相簿中一個(gè)相冊(cè)或者照片中一個(gè)時(shí)刻,或者是一個(gè)特殊的“智能相冊(cè)”。這種智能相冊(cè)包括所有的視頻集合,最近添加的項(xiàng)目,用戶收藏,所有連拍照片等//PHCollectionList 則是包含PHCollection的PHCollection。因?yàn)樗旧砭褪荘HCollection,所以集合列表可以包含其他集合列表,它們?cè)试S復(fù)雜的集合繼承。例子:年度->精選->時(shí)刻//PHFetchResult 某個(gè)系列(PHAssetCollection)或者是相冊(cè)(PHAsset)的的返回結(jié)果,一個(gè)集合類型,PHAsset或者PHAssetCollection的類方法均可以獲取到//PHImageManager 處理圖片加載,加載圖片過程有緩存處理//PHCachingImageManager(PHImageManager的抽象) 處理圖像的整個(gè)加載過程的緩存要加載大量資源的縮略圖時(shí)可以使用該類的startCachingImage...預(yù)先將圖像加載到內(nèi)存中 ,使用時(shí)注意size要一致//PHImageRequestOptions設(shè)置加載圖片方式的參數(shù)()//PHFetchOptions集合資源的配置方式(按一定的(例如時(shí)間)順序?qū)Y源進(jìn)行排列、隱藏/顯示某一個(gè)部分的資源集合)

先挑明自己踩到的坑..

/* 1、 首次加載APP時(shí)出現(xiàn)的問題:僅會(huì)獲取相應(yīng)的權(quán)限 而不會(huì)響應(yīng)方法 */ //每次訪問相冊(cè)都會(huì)調(diào)用這個(gè)handler 檢查改app的授權(quán)情況 //phphotoLibrary [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { if (status == PHAuthorizationStatusAuthorized) { //code } }]; /* 2、獲取所有圖片(注意不能在膠卷中獲取圖片,因?yàn)槟z卷中的圖片包含了video的顯示圖) */ [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];//這樣獲取 /* 3、使用PHImageManager請(qǐng)求時(shí)的回調(diào)同步or異步時(shí)、block回調(diào)次數(shù)的問題 */ /* 4、回調(diào)得出的圖片size的問題: 由3個(gè)參數(shù)決定 */ /* 在ShowAlbumViewController 中觀察 在PHImageContentModeaspectFill 下 圖片size 有一個(gè)分水嶺 {125,125} {126,126} 當(dāng)imageOptions.resizeMode = PHImageRequestOptionsResizeModeExact; 時(shí): 設(shè)置size 小于{125,125}時(shí),你得到的圖片size 將會(huì)是設(shè)置的1/2 而在PHImageContentModeAspectFit 分水嶺 {120,120} {121,121} */ /* 5、回調(diào)中info字典key消失的問題: 當(dāng)最終獲取到的圖片的size的高/寬沒有一個(gè)能達(dá)到原有的圖片size的高/寬時(shí) 部分key 會(huì)消失 */

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

在collectionView中

- (void)getAllPhotosFromAlbum {//配置簡(jiǎn)單 ,但是參數(shù)卻是比價(jià)多且 self.options= [[PHImageRequestOptions alloc] init];//請(qǐng)求選項(xiàng)設(shè)置 self.options.resizeMode=PHImageRequestOptionsResizeModeExact;//resizeMode 自定義設(shè)置圖片的大小 枚舉類型*// PHImageRequestOptionsResizeMode:*//PHImageRequestOptionsResizeModeNone = 0, //保持原size//PHImageRequestOptionsResizeModeFast, //高效、但不保證圖片的size為自定義size//PHImageRequestOptionsResizeModeExact, //嚴(yán)格按照自定義size self.options.synchronous=YES; //YES 一定是同步 NO不一定是異步 imageOptions.resizeMode = PHImageRequestOptionsResizeModeExact; /* PHImageRequestOptionsResizeModeNone // 不調(diào)整大小 PHImageRequestOptionsResizeModeFast // 由系統(tǒng)去安排,情況不定:有時(shí)你設(shè)置的size比較低,會(huì)根據(jù)你設(shè)的size,有時(shí)又會(huì)比 PHImageRequestOptionsResizeModeExact// 保證精確到自定義size :此處精確的前提得用PHImageContentModeAspectFill */ //simageOptions.version = PHImageRequestOptionsVersionCurrent;//版本 iOS8.0之后出的圖片編輯extension,可以根據(jù)次枚舉獲取原圖或者是經(jīng)編輯過的圖片, /*PHImageRequestOptionsVersion: PHImageRequestOptionsVersionCurrent = 0, //當(dāng)前的(編輯過?經(jīng)過編輯的圖:原圖) PHImageRequestOptionsVersionUnadjusted, //經(jīng)過編輯的圖 PHImageRequestOptionsVersionOriginal //原始圖片 */ // imageOptions.networkaccessAllowed = YES;//用于開啟iClould中下載圖片 // imageOptions.PRogressHandler //iClould下載進(jìn)度的回調(diào) imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;//在imageOptions.synchronous = NO的情況下最終決定是否是異步//容器類 (PHFetchResult *) self.assets= [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil]; //此處option是對(duì)獲取得到對(duì) Collection 的配置 我只是把它設(shè)為nil了 可以這樣使用 /*//例如按資源的創(chuàng)建時(shí)間進(jìn)行一個(gè)排序 PHFetchOptions *options = [[PHFetchOptions alloc] init];// NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:nil ascending:YES]; options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]]; //其中:key是PHAsset類的屬性 這是一個(gè)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ù)雜 下面由說到 //返回一個(gè) PHImageRequestID,在異步請(qǐng)求時(shí)可以根據(jù)這個(gè)ID去取消請(qǐng)求,同步就沒辦法了.. [[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 決定的,當(dāng)然也有我們?cè)O(shè)定的size 優(yōu)先級(jí)而言 PHImageRequestOptions > PHImageContentMode */ //這個(gè)handler 并非在主線程上執(zhí)行,所以如果有UI的更新操作就得手動(dòng)添加到主線程中// 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. .........異步就這個(gè)回調(diào)會(huì)調(diào)用1或多次....#pragma If -[PHImageRequestOptions isSynchronous] returns YES, resultHandler will be called exactly once同步就1次.//一開始本來打算是利用數(shù)據(jù)吧所有的相片先存起來的.但是發(fā)現(xiàn)同步會(huì)卡UI 但是異步又會(huì)被回調(diào)多次,我的數(shù)組都變成double了...只好把任務(wù)方法方法cellforItem中 cell.photoImageView.contentMode = UIViewContentModeScaleAspectFit; cell.photoImageView.image = result;}]; return cell;}/*注意這個(gè)info字典 有時(shí)這個(gè)info甚至為null 慎用 里面的key是比較奇怪的 盡量不要用里面的key 因?yàn)檫@個(gè)key 會(huì)變動(dòng): 當(dāng)我們最終獲取到的圖片的size的高/寬 沒有一個(gè)達(dá)到能原有的圖片size的高/寬時(shí) 部分key 會(huì)消失 如 PHImageFileSandboxExtensionTokenKey , PHImageFileURLKey */ /* 在PHImageContentModeAspectFill 下 圖片size 有一個(gè)分水嶺 {125,125} {126,126} 當(dāng)imageOptions.resizeMode = PHImageRequestOptionsResizeModeExact; 時(shí): 設(shè)置size 小于{125,125}時(shí),你得到的圖片size 將會(huì)是設(shè)置的1/2 而在PHImageContentModeAspectFit 分水嶺 {120,120} {121,121} 至于為什么會(huì)這樣???我不知道 - - 可能蘋果考慮性能吧...誰知道告訴下啊 */

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

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

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

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

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

大家不要誤會(huì),第一張圖片的原圖是肯定大于{300,300} 的,為什么顯示不是{300,300},因?yàn)槲沂褂锰幚韴D片的模式為PHImageContentModeAspectFit,所以顯示下來的并非我們{300,300}而是保留原圖的比例,大家可以動(dòng)手去試一試

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

或許是這個(gè)size出的問題吧,會(huì)導(dǎo)致如果我要根據(jù)這個(gè)PHimageFileKey 獲取本地的圖片的時(shí)候就因?yàn)槟巢糠值膇mage因?yàn)閟ize的原因缺少這個(gè)key使得找不到這張圖,使得我app出現(xiàn)bug....不過這個(gè)方法真的挺不安全的,建議是把返回的result 那張image 寫進(jìn)tmp里面 再使用吧。。。。

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

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

我這邊配合的resizeMode模式為強(qiáng)制自定義的圖片大小,即:self.options.resizeMode=PHImageRequestOptionsResizeModeExact;//嚴(yán)格按照自定義圖片大小的加載模式如果不是這個(gè)枚舉的話,返回的PHImageRequestOptionsDeliveryModeOpportunistic第一次返回的縮略圖,以及PHImageRequestOptionsDeliveryModeFastFormat所返回的縮略圖最小默認(rèn)是{60,60},PHImageRequestOptionsResizeModeExact則可以隨意設(shè)置值得注意的是,當(dāng)我們選擇的是PHImageRequestOptionsDeliveryModeOpportunistic時(shí),返回的次數(shù)是跟size有關(guān)系的,你設(shè)定的的size 太小的話僅會(huì)回調(diào)一次,大的話,首次返回的是一個(gè)小的縮略圖(這個(gè)縮略圖最大是{60,60},具體值根據(jù)比例),二次回調(diào)才會(huì)得到我們想要的圖片總而言之,圖片的真實(shí)size跟resizeMode和PHImageRequestOptionsDeliveryMode以及我們?cè)O(shè)定的size都有關(guān)聯(lián)吧,具體應(yīng)用的時(shí)候就要多試試幾次,觀察自己真實(shí)所需吧...接下來的是我要找的是視頻......問題又出現(xiàn)了,這個(gè)PhotoKit有提供查找視頻的方式么...然后我把這修改了一下。。。改成了找Video 的元數(shù)據(jù) 哈哈哈哈哈哈哈self.assets= [PHAsset fetchAssetsWithMediaType:**PHAssetMediaTypeVideo** options:nil];

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

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

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

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。。。這個(gè)key里面

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

很不安全,我真的怕這個(gè)key突然又因?yàn)槭裁丛蚨鴐iss掉了........然后我看了看asset 的類型 發(fā)現(xiàn)它的類型為AVURLAsset,有點(diǎn)意思,看看里面發(fā)現(xiàn)了一個(gè)是有個(gè)URL屬性的!而且是asset的絕對(duì)路徑,簡(jiǎn)直完美...

//video路徑獲取if (asset && [asset isKindOfClass:[AVURLAsset class]] && [NSString stringWithFormat:@"%@",((AVURLAsset *)asset).URL].length > 0) { NSString *videoURLStr = [NSString stringWithFormat:@"%@",((AVURLAsset *)asset).URL]; videoPath = [videoURLStr substringWithRange:NSMakeRange([videoURLStr rangeOfString:@"/"].location, videoURLStr.length -[videoURLStr rangeOfString:@"/"].location)];}//這個(gè)截取字符串的操作柑橘的多余的

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

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

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

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

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

collection cell 沒處理,不過效果還是顯而易見的,同個(gè)一個(gè)tableView 去選取自己想要找的部分即可中間那七張相同的圖片其實(shí)是我放入系統(tǒng)中的七個(gè)相同視頻的圖片...

解釋一下

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

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

參考文章:http://objccn.io/issue-21-4/#PhotoKit-Object-Modelhttp://kayosite.com/ios-development-and-detail-of-photo-framework-part-two.html


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 桃园市| 古蔺县| 高尔夫| 义马市| 惠州市| 嘉兴市| 都昌县| 绥中县| 玉树县| 岚皋县| 东港市| 大悟县| 涡阳县| 邮箱| 通渭县| 二连浩特市| 洛宁县| 古蔺县| 壤塘县| 安泽县| 红原县| 棋牌| 米林县| 海南省| 桦川县| 乌恰县| 宁安市| 伊宁市| 柏乡县| 石楼县| 榆林市| 巫溪县| 襄樊市| 武安市| 临西县| 合川市| 樟树市| 甘德县| 平谷区| 山东| 留坝县|