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

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

iOS開發(fā)之獲取系統(tǒng)相冊中的圖片與視頻教程(內帶url轉換)

2020-07-26 03:06:17
字體:
來源:轉載
供稿:網(wǎng)友

好些天沒寫點東西了,最近公司要做新項目,有點小忙。不想我的堅持就此中斷,我把我前些天研究的東西拿出來給大家看看。

這次整理的是AssetsLibrary和PhotoKit的使用。本人處女座,有點強迫癥,之前寫的項目里用的是AssetsLibrary寫的調取相冊內的媒體文件,但是Xcode總是報警告錯誤,雖然能夠編譯并展示效果,但是十幾個警告錯誤掛在那,心里總不是滋味,所以我就研究了一下AssetLibrary和PhotoKit。

在 iOS 8 出現(xiàn)之前,開發(fā)者只能使用 AssetsLibrary 框架來訪問設備的照片庫,這是一個有點跟不上 iOS 應用發(fā)展步伐以及代碼設計原則但確實強大的框架,考慮到 iOS7 仍占有不少的滲透率,因此 AssetsLibrary 也是本文重點介紹的部分。而在 iOS8 出現(xiàn)之后,蘋果提供了一個名為 PhotoKit 的框架,一個可以讓應用更好地與設備照片庫對接的框架。

一、AssetsLibrary 組成

AssetsLibrary 的組成比較符合照片庫本身的組成,照片庫中的完整照片庫對象、相冊、相片都能在 AssetsLibrary 中找到一一對應的組成,這使到 AssetsLibrary 的使用變得直觀而方便。想要了解AssetsLibrary得從它的類開始。

AssetsLibrary: 代表整個設備中的資源庫(照片庫),通過 AssetsLibrary 可以獲取和包括設備中的照片和視頻

  • ALAssetsGroup: 映射照片庫中的一個相冊,通過 ALAssetsGroup 可以獲取某個相冊的信息,相 冊下的資源,同時也可以對某個相冊添加資源。
  • ALAsset: 映射照片庫中的一個照片或視頻,通過 ALAsset 可以獲取某個照片或視頻的詳細信息, 或者保存照片和視頻。
  • ALAssetRepresentation: ALAssetRepresentation 是對 ALAsset 的封裝(但不是其子類),可以更方便地獲取 ALAsset 中的資源信息,每個 ALAsset 都有至少有一個 ALAssetRepresentation 對象,可以通過 defaultRepresentation 獲取。而例如使用系統(tǒng)相機應用拍攝的 RAW + JPEG 照片,則會有兩個 ALAssetRepresentation,一個封裝了照片的 RAW 信息,另一個則封裝了照片的 JPEG 信息。

@話不多說,直接上代碼

#import <AssetsLibrary/AssetsLibrary.h> // 必須導入  // 照片原圖路徑 #define KOriginalPhotoImagePath  / [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"OriginalPhotoImages"]  // 視頻URL路徑 #define KVideoUrlPath  / [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"VideoURL"]  // caches路徑 #define KCachesPath  / [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]  // MainViewController @interface MTHMainViewController ()  @property (nonatomic,strong) MTHNextViewController *nextVC; @property (nonatomic,strong) NSMutableArray    *groupArrays; @property (nonatomic,strong) UIImageView      *litimgView;  @end  @implementation MTHMainViewController  - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {   self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];   if (self) {     // Custom initialization   }   return self; }  - (void)viewDidLoad {   [super viewDidLoad];   // Do any additional setup after loading the view.   self.navigationItem.title = @"Demo";   self.view.backgroundColor = [UIColor clearColor];      // 初始化   self.groupArrays = [NSMutableArray array];      // 測試BarItem   self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"測試" style:UIBarButtonItemStylePlain target:self action:@selector(testRun)];      // 測試手勢   UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didClickPanGestureRecognizer:)];   [self.navigationController.view addGestureRecognizer:panRecognizer];      // 圖片或者視頻的縮略圖顯示   self.litimgView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 200, 120, 120)];   [self.view addSubview:_litimgView]; }   - (void)testRun {   __weak MTHMainViewController *weakSelf = self;   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{     ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOLBOOL *stop) {       if (group != nil) {         [weakSelf.groupArrays addObject:group];       } else {         [weakSelf.groupArrays enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOLBOOL *stop) {           [obj enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOLBOOL *stop) {             if ([result thumbnail] != nil) {               // 照片               if ([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]){                                  NSDate *date= [result valueForProperty:ALAssetPropertyDate];                 UIImage *image = [UIImage imageWithCGImage:[result thumbnail]];                 NSString *fileName = [[result defaultRepresentation] filename];                 NSURL *url = [[result defaultRepresentation] url];                 int64_t fileSize = [[result defaultRepresentation] size];                                  NSLog(@"date = %@",date);                 NSLog(@"fileName = %@",fileName);                 NSLog(@"url = %@",url);                 NSLog(@"fileSize = %lld",fileSize);                                  // UI的更新記得放在主線程,要不然等子線程排隊過來都不知道什么年代了,會很慢的                 dispatch_async(dispatch_get_main_queue(), ^{                   self.litimgView.image = image;                 });               }               // 視頻               else if ([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo] ){                                // 和圖片方法類似               }             }           }];         }];        }     };          ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error)     {              NSString *errorMessage = nil;              switch ([error code]) {         case ALAssetsLibraryAccessUserDeniedError:         case ALAssetsLibraryAccessGloballyDeniedError:           errorMessage = @"用戶拒絕訪問相冊,請在<隱私>中開啟";           break;                    default:           errorMessage = @"Reason unknown.";           break;       }              dispatch_async(dispatch_get_main_queue(), ^{         UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"錯誤,無法訪問!"                                   message:errorMessage                                  delegate:self                              cancelButtonTitle:@"確定"                              otherButtonTitles:nil, nil nil];         [alertView show];       });     };               ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];     [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll                    usingBlock:listGroupBlock failureBlock:failureBlock];   }); } 


@但是:
按照上面方法直接取出來的路徑是無法傳輸?shù)?必須自己轉化成NSData對象重新寫入沙盒路徑

   // 將原始圖片的URL轉化為NSData數(shù)據(jù),寫入沙盒 - (void)imageWithUrl:(NSURL *)url withFileName:(NSString *)fileName {   // 進這個方法的時候也應該加判斷,如果已經(jīng)轉化了的就不要調用這個方法了   // 如何判斷已經(jīng)轉化了,通過是否存在文件路徑   ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];   // 創(chuàng)建存放原始圖的文件夾--->OriginalPhotoImages   NSFileManager * fileManager = [NSFileManager defaultManager];   if (![fileManager fileExistsAtPath:KOriginalPhotoImagePath]) {     [fileManager createDirectoryAtPath:KOriginalPhotoImagePath withIntermediateDirectories:YES attributes:nil error:nil];   }   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{     if (url) {       // 主要方法       [assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {         ALAssetRepresentation *rep = [asset defaultRepresentation];         Byte *buffer = (Byte*)malloc((unsigned long)rep.size);         NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:((unsigned long)rep.size) error:nil];         NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];         NSString * imagePath = [KOriginalPhotoImagePath stringByAppendingPathComponent:fileName];         [data writeToFile:imagePath atomically:YES];       } failureBlock:nil];     }   }); }  // 將原始視頻的URL轉化為NSData數(shù)據(jù),寫入沙盒 - (void)videoWithUrl:(NSURL *)url withFileName:(NSString *)fileName {   // 解析一下,為什么視頻不像圖片一樣一次性開辟本身大小的內存寫入?   // 想想,如果1個視頻有1G多,難道直接開辟1G多的空間大小來寫?   ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{     if (url) {       [assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {         ALAssetRepresentation *rep = [asset defaultRepresentation];         NSString * videoPath = [KCachesPath stringByAppendingPathComponent:fileName];         char constconst *cvideoPath = [videoPath UTF8String];         FILEFILE *file = fopen(cvideoPath, "a+");         if (file) {           const int bufferSize = 11024 * 1024;           // 初始化一個1M的buffer           Byte *buffer = (Byte*)malloc(bufferSize);           NSUInteger read = 0, offset = 0, written = 0;           NSError* err = nil;           if (rep.size != 0)           {             do {               read = [rep getBytes:buffer fromOffset:offset length:bufferSize error:&err];               written = fwrite(buffer, sizeof(char), read, file);               offset += read;             } while (read != 0 && !err);//沒到結尾,沒出錯,ok繼續(xù)           }           // 釋放緩沖區(qū),關閉文件           free(buffer);           buffer = NULL;           fclose(file);           file = NULL;         }       } failureBlock:nil];     }   }); } 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 若尔盖县| 临洮县| 通化市| 花垣县| 海门市| 铜山县| 武功县| 桃园县| 敖汉旗| 江陵县| 兰州市| 四平市| 通江县| 隆回县| 辽宁省| 柏乡县| 醴陵市| 土默特左旗| 烟台市| 巴里| 浦东新区| 肃宁县| 德化县| 咸阳市| 伊金霍洛旗| 水城县| 莒南县| 清丰县| 穆棱市| 晋城| 秦皇岛市| 磴口县| 全州县| 杨浦区| 铁力市| 铁力市| 甘孜| 莫力| 黄浦区| 乌兰察布市| 新干县|