获取IOS系统相册中的照片

获取IOS系统相册中的照片

在iOS中,我们调用摄像头和选择相册中的资源,我们可以使用:UIImagePickerController类来完成。

 

当然,我们也可以不使用UI的形式来访问iOS设备的相册资源。

那就是使用:ALAssetsLibrary

 

可以说,是一个桥梁吧。连接了我们应用程序和相册之间的访问。

ALAssetsLibrary提供了我们对iOS设备中的相片、视频的访问。

具体方法如下:

1 导入框架 AssetLibrary

// 这个头文件

#import

 

2.流程:取得数据库(AssetsLibarary),遍历数据库得到所有相册(ALAssetsGroup),然后,遍历每个相册,得到图片(ALAsset)

//1.把整个相册看做一个数据库    --对应着ALAssetsLibarary
//2.然后是相册库中的文件夹      --对应着ALAssetsGroup
//3.然后就是具体的照片或者视频 --对应着ALAsset
 
//拿到相册库,然后拿到文件夹,然后拿到具体照片
ALAssetsLibrary * libary= [[ALAssetsLibrary alloc]init];
 
/*
    1.通告相册库,遍历出所有的文件夹ALAssetsGroup
 <#(ALAssetsGroupType)#>    我们使用最后一个
 ALAssetsGroupLibrary              // The Library group that includes all assets.
 ALAssetsGroupAlbum              // All the albums synced from iTunes or created on the device.
 ALAssetsGroupEvent               // All the events synced from iTunes.
 ALAssetsGroupFaces
ALAssetsGroupAll               //The same as ORing together all the available group types,
 
 第二个是 usingBlock,有多少文件夹,就会调用多少次次这个blcok,每次
 调用block会将对应的文件夹group对象传过来
 
 第三个是 失败之后调用的block
 */
//  ALAssetsGroupAll 取得全部类型
 [libary enumerateGroupsWithTypes: ALAssetsGroupAllusingBlock:^(ALAssetsGroup *group, BOOL *stop) {
       
        //但是这个group有可能为空,所以判断一下
        if(group != Nil)
       {
            //2.再通告文件夹遍历其中的资源文件
           [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
                //index就是他的位置
                //ALAsset 的这个result 就是我们要的图片
                //两种情况
                //单选的话,这个界面是自带的
                //多选的话,没有提供界面,但是提供了照片的资源,我们可以创建一个tableview来弄
                //这个地方我们一般是找一个model或者数组来接受
               
                //用数组保存起来
               [_dataArr addObject:result];
           }];
       }
   } failureBlock:^(NSError *error) {
   }];
}


3.用一个tableView 来读取数据

 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _dataArr.count;
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"identifier"];
    if(cell == nil)
   {
       cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"identifier"];
        //取出数据
        ALAsset *asset = [_dataArr objectAtIndex:indexPath.row];
        NSString * type = [asset valueForProperty:ALAssetPropertyType];
        //这是总体的类型
        // 这个类型不只是图片。还可能是视频,所以判断一下
        if([type isEqualToString:ALAssetTypePhoto])
       {
           cell.textLabel.text = @"照片";
           
       }else if([type isEqualToString:ALAssetTypeVideo])
       {
           cell.textLabel.text = @"视频";
           
       }else if([type isEqualToString:ALAssetTypeUnknown])
       {
           cell.textLabel.text = @"未知类型";
       }
        //取得缩略图
        CGImageRef cmimg = [asset thumbnail];
        UIImage * img = [UIImage imageWithCGImage:cmimg];
       cell.imageView.image = img;
   }
    return cell;
}

 4.取出图片

   

ALAssetRepresentation *rap = [asset defaultRepresentation];
    //还可以取得fullScreenImage 特大图
    CGImageRef ref = [rap fullResolutionImage];
    UIImage * img = [UIImage imageWithCGImage:ref];

5.注意:

1.   The lifetimes of objectsyou get back from a library instance are tied to the lifetime of the libraryinstance. 
通过ALAssetsLibrary对象获取的其他对象只在该ALAssetsLibrary对象生命期内有效,若ALAssetsLibrary对象被销毁,则其他从它获取的对象将不能被访问,否则会有错误。具体方法:ARC和非ARC区别,ARC的时候,需要将ALAssetsLibrary * libary定义为全局

MRC的时候,libary不能release

 

2.  ALAssetRepresentation metadata 方法很慢,我在iPhone4 iOS5.1.1中测试,此方法返回需要40-50ms,所以获取图片的个各种属性尽量直接从ALAssetRepresentation中获取,不要读取metadata 这里 给出了一个此方法占用内存过多的解释,调用多次也确实很容易会memory warning,或许也能解析其为什么很慢吧。

3.   系统相册程序显示的图片是 fullScreenImage ,而不是fullResolutionImage fullResolutionImage尺寸太大,在手机端显示推荐用fullScreenImage 

fullScreenImage已被调整过方向,可直接使用

[UIImage imageWithCGImage:representation.fullScreenImage];

 使用fullResolutionImage要自己调整方法和scale,

 [UIImage imageWithCGImage:representation.fullResolutionImage scale:representation.scale      orientation:representation.orientation];

 

  4.遍历Assets Group

         使用 enumerateGroupsWithTypes:usingBlock:failureBlock: 方法可遍历assets group

         此方法为异步执行,若之前未被授权过,此方法会向用户请求访问数据的权限;若用户拒绝授权或其他错误则会执行failureBlock

         如果用户关掉了位置服务(Location Services,在设置->通用中),返回的错误为ALAssetsLibraryAccessGloballyDeniedError 

         enumerationBlockfailureBlock与在调用此方法的线程内执行,若要在背景线程进行遍历,可将遍历代码放入GCDNSOperation中。

 

 

   5.遍历Assets Group中的Assets

         使用 enumerateAssetsUsingBlock: 方法或者其他遍历方法可遍历ALAssetsGroup中的所有ALAsset;

         可通过 setAssetsFilter: 设置过滤器ALssetsFilter )使enumerateAssetsUsingBlock:只返回特定类型asset,而 numberOfAssets 只返回特定类型asset的数量。 
可以设置只显示Photo( allPhotos ),只显示Video( allVideos ),或显示全部(allAssets )

         enumerateAssetsUsingBlock:为同步方法,只有所有Asset遍历完才返回。所以需要将遍历代码放入背景线程,防止阻塞UI线程。

 

6.根据url获取asset

使用ALAssetsLibrary assetForURL:resultBlock:failureBlock: 方法,可根据之前从ALAssetRepresentation中获取的url重新获取ALAsset对象,此方法同enumerateGroupsWithTypes:usingBlock:failureBlock:一样为异步方法。

 

6.获取Assets的各种属性

1.           相册封面图片 [assetsGroup posterImage ];

2.           照片url[[[asset defaultRepresentation] url]absoluteString];

3.           照片缩略图 
[asset thumbnail]; 
[assetaspectRatioThumbnail];

4.           照片全尺寸图 
[[asset defaultRepresentation]fullResolutionImage];

5.           照片全屏图 
[[asset defaultRepresentation]fullScreenImage];

6.           照片创建时间 
[assetvalueForProperty:ALAssetPropertyDate];

7.           照片拍摄位置(可能为nil) 
[assetvalueForProperty:ALAssetPropertyLocation];

8.           照片尺寸 
[[asset defaultRepresentation]dimensions];

 

你可能感兴趣的:(IOS开发)