zoukankan      html  css  js  c++  java
  • ALAssetsLibrary 照片相关 浅析

    ALAssetsLibrary 提供了访问iOS设备下”照片”应用下所有照片和视频的接口;

    1. 从 ALAssetsLibrary 中可读取所有的相册数据,即 ALAssetsGroup 对象列表;
    2. 从每个 ALAssetsGroup 中可获取到其中包含的照片或视频列表,即 ALAsset 对象列表;
    3. 每个 ALAsset 可能有多个representations表示,即 ALAssetRepresentation 对象,使用其 defaultRepresentation 方法可获得其默认representations,使用[asset valueForProperty: ALAssetPropertyRepresentations ]可获取其所有representations的 UTI 数组。
    4. 从ALAsset对象可获取缩略图 thumbnail 或 aspectRatioThumbnail ;
    5. 从 ALAssetRepresentation 对象可获取全尺寸图片( fullResolutionImage ),全屏图片( fullScreenImage )及图片的各种属性: orientation , dimensions, scale , url , metadata 等。

    其层次关系为 ALAssetsLibrary -> ALAssetsGroup -> ALAsset ->ALAssetRepresentation 。

    注意:

    1. The lifetimes of objects you get back from a library instance are tied to the lifetime of the library instance.

      通过ALAssetsLibrary对象获取的其他对象只在该ALAssetsLibrary对象生命期内有效,若ALAssetsLibrary对象被销毁,则其他从它获取的对象将不能被访问,否则有会错误。 

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

      The method [representation metadata] returns an autoreleased object and possibly creates more autoreleased objects when it executes. All these instances are added to the autorelease pool, waiting to be finally released (and their memory freed) when the ARP gets the chance to drain itself.

    3. 系统”相册”程序显示的图片是 fullScreenImage ,而不是 fullResolutionImage ,fullResolutionImage尺寸太大,在手机端显示推荐用fullScreenImage。 
      fullScreenImage已被调整过方向,可直接使用,即
      [UIImage imageWithCGImage:representation.fullScreenImage];
      

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

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

    二.创建 ALAssetsLibrary对象

    使用ALAssetsLibrary之前需导入头文件和AssetsLibrary.framework。

    
      #import 
     
      
      ...
      ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc]init];
      ...
    
     
    

    三.遍历Assets Group

    • 使用 enumerateGroupsWithTypes:usingBlock:failureBlock: 方法可遍历assets group;
    • 此方法为异步执行,若之前未被授权过,此方法会向用户请求访问数据的权限;若用户拒绝授权或其他错误则会执行failureBlock;
    • 如果用户关掉了位置服务(Location Services,在设置->通用中),返回的错误为ALAssetsLibraryAccessGloballyDeniedError 。
    • enumerationBlock和failureBlock与在调用此方法的线程内执行,若要在背景线程进行遍历,可将遍历代码放入GCD或NSOperation中。
    
        [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
            if (!group) {
                [tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
            }else{
                [groupsArray addObject:group];
                ...
            }
    
        } failureBlock:^(NSError *error) {
            NSLog(@"error:%@",error);
        }];
    
    

    四.遍历Assets Group中的Assets

    • 使用 enumerateAssetsUsingBlock: 方法或者其他变体方法可遍历ALAssetsGroup中的所有ALAsset;
    • 可通过 setAssetsFilter: 设置过滤器( ALssetsFilter )使enumerateAssetsUsingBlock:只返回特定类型asset,而 numberOfAssets 只返回特定类型asset的数量。 
      可以设置只显示Photo( allPhotos ),只显示Video( allVideos ),或显示全部(allAssets )。
    • enumerateAssetsUsingBlock:为同步方法,只有所有Asset遍历完才返回。所以需要将遍历代码放入背景线程,防止阻塞UI线程。
    
        [assetsGroup setAssetsFilter:[ALAssetsFilter allPhotos]];
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [assetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
                if (!result) {
                    [tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
                }else{
                    [assetsArray addObject:result];
                    ...
                }
            }];
        });
    
    

    五.根据url获取asset

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

    六.获取Assets的各种属性

      1. 相册封面图片 [assetsGroup posterImage ];
      2. 照片url[[[asset defaultRepresentation] url] absoluteString];
      3. 照片缩略图 
        [asset thumbnail]; 
        [asset aspectRatioThumbnail];
      4. 照片全尺寸图 
        [[asset defaultRepresentation] fullResolutionImage];
      5. 照片全屏图 
        [[asset defaultRepresentation] fullScreenImage];
      6. 照片创建时间 
        [asset valueForProperty:ALAssetPropertyDate];
      7. 照片拍摄位置(可能为nil) 
        [asset valueForProperty:ALAssetPropertyLocation];
      8. 照片尺寸 
        [[asset defaultRepresentation] dimensions];

    添加AssetsLibrary.framework
    然后引入

    #import <AssetsLibrary/ALAssetsLibrary.h>

    一个获取所有图片的类

    .h

    #import <UIKit/UIKit.h>
    #include<AssetsLibrary/AssetsLibrary.h> 
    
    @interface ViewController : UIViewController{
        ALAssetsLibrary *library;
        
        NSArray *imageArray;
        
        NSMutableArray *mutableArray;
    }
    -(void)allPhotosCollected:(NSArray*)imgArray;
    @end

    .m

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    static int count=0;
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        [self getAllPictures];
    }
    
    //获取所有图片
    -(void)getAllPictures
    
    {
        imageArray=[[NSArray alloc] init];
        mutableArray =[[NSMutableArray alloc]init];
        NSMutableArray* assetURLDictionaries = [[NSMutableArray alloc] init];
        library = [[ALAssetsLibrary alloc] init];
        void (^assetEnumerator)( ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
            if(result != nil) {
                if([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
                    [assetURLDictionaries addObject:[result valueForProperty:ALAssetPropertyURLs]];
                    NSURL *url= (NSURL*) [[result defaultRepresentation]url];
                    
                    [library assetForURL:url
                     
                             resultBlock:^(ALAsset *asset) {
                                 
                                 [mutableArray addObject:[UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage]]];
    
                                 if ([mutableArray count]==count)
                                     
                                 {
                                     
                                     imageArray=[[NSArray alloc] initWithArray:mutableArray];
                                     
                                     [self allPhotosCollected:imageArray];
                                     
                                 }
                                 
                             }
                            failureBlock:^(NSError *error){ NSLog(@"operation was not successfull!"); } ];
                }
                
            }
            
        };
    
        NSMutableArray *assetGroups = [[NSMutableArray alloc] init];
        void (^ assetGroupEnumerator) ( ALAssetsGroup *, BOOL *)= ^(ALAssetsGroup *group, BOOL *stop) {
            
            if(group != nil) {
                
                [group enumerateAssetsUsingBlock:assetEnumerator];
                
                [assetGroups addObject:group];
                
                count=[group numberOfAssets];
                
            }
            
        };
        assetGroups = [[NSMutableArray alloc] init];
        [library enumerateGroupsWithTypes:ALAssetsGroupAll
         
                               usingBlock:assetGroupEnumerator
         
                             failureBlock:^(NSError *error) {NSLog(@"There is an error");}];
        
    }
    
    
    
    -(void)allPhotosCollected:(NSArray*)imgArray
    {
        //write your code here after getting all the photos from library...
        NSLog(@"all pictures are %@",imgArray);
    }
    
    
    @end

    以下是关于AssetsLibrary的一些方法说明,仅供参考

    //初始化,这个简单
    if (!self.assetsLibrary) {
    _assetsLibrary = [[ALAssetsLibrary alloc] init];
    }
    //添加一个group,成功后查看一些信息
    [_assetsLibrary addAssetsGroupAlbumWithName:@"tesddt" resultBlock:^(ALAssetsGroup *group) {
    //查看相册的名字
    NSLog(@"ALAssetsGroupPropertyName:%@",[group valueForProperty:ALAssetsGroupPropertyName]);
    //查看相册的类型
    NSLog(@"ALAssetsGroupPropertyType:%@",[group valueForProperty:ALAssetsGroupPropertyType]);
    //查看相册的存储id
    NSLog(@"ALAssetsGroupPropertyPersistentID:%@",[group valueForProperty:ALAssetsGroupPropertyPersistentID]);
    //查看相册存储的位置地址
    NSLog(@"ALAssetsGroupPropertyURL:%@",[group valueForProperty:ALAssetsGroupPropertyURL]);
    } failureBlock:^(NSError *error) {
    
    }];
    

    可以通过valueForProperty获取到图片的信息,包括类型, Location , 时长,方向,日期,格式 , URL地址。
    NSString * nsALAssetPropertyType = [ asset valueForProperty:ALAssetPropertyType ] ;
    NSString * nsALAssetPropertyLocation = [ asset valueForProperty:ALAssetPropertyLocation ] ;
    NSString * nsALAssetPropertyDuration = [ asset valueForProperty:ALAssetPropertyDuration ] ;
    NSString * nsALAssetPropertyOrientation = [ asset valueForProperty:ALAssetPropertyOrientation ] ;
    NSString * nsALAssetPropertyDate = [ asset valueForProperty:ALAssetPropertyDate ] ;
    NSString * nsALAssetPropertyRepresentations = [ asset valueForProperty:ALAssetPropertyRepresentations ] ;
    NSString * nsALAssetPropertyURLs = [ asset valueForProperty:ALAssetPropertyURLs ] ;
    NSString * nsALAssetPropertyAssetURL = [ asset valueForProperty:ALAssetPropertyAssetURL ] ;

    //通过url地址在相册资源中获取该地址的资源文件ALAsset,有可能是相片或视频
    [_library assetForURL:[NSURL URLWithString:@""] resultBlock:^(ALAsset *asset) {
    
    
    //     NSString *const ALAssetPropertyType;
    //     NSString *const ALAssetPropertyLocation;
    //     NSString *const ALAssetPropertyDuration;
    //     NSString *const ALAssetPropertyOrientation;
    //     NSString *const ALAssetPropertyDate;
    //     NSString *const ALAssetPropertyRepresentations;
    //     NSString *const ALAssetPropertyURLs;
    //     NSString *const ALAssetPropertyAssetURL;
    
    
    
    //查看资源的地理位置信息
    NSLog(@"ALAssetPropertyLocation:%@",[asset valueForProperty:ALAssetPropertyLocation]);
    //如果资源是视频,查看视频的时长
    NSLog(@"ALAssetPropertyDuration:%@",[asset valueForProperty:ALAssetPropertyDuration]);
    //查看资源的方向,图片的旋转方向
    NSLog(@"ALAssetPropertyOrientation:%@",[asset valueForProperty:ALAssetPropertyOrientation]);
    //查看资源的创建时间
    NSLog(@"ALAssetPropertyDate:%@",[asset valueForProperty:ALAssetPropertyDate]);
    //查看资源的描述信息
    NSLog(@"ALAssetPropertyRepresentations:%@",[asset valueForProperty:ALAssetPropertyRepresentations]);
    NSLog(@"ALAssetPropertyURLs:%@",[asset valueForProperty:ALAssetPropertyURLs]);
    //查看资源的url路径
    NSLog(@"ALAssetPropertyAssetURL:%@",[asset valueForProperty:ALAssetPropertyAssetURL]);
    } failureBlock:^(NSError *error) {
    
    }];
    //通过url地址获取相册资源中的一个相册
    [_library groupForURL:groupURL resultBlock:^(ALAssetsGroup *group) {
    NSLog(@"ALAssetsGroupPropertyName:%@",[group valueForProperty:ALAssetsGroupPropertyName]);
    } failureBlock:^(NSError *error) {
    
    }];
    
    //根据选择的类型遍历相册资源中的相对应类型的所有相册,其中stop行参是指针,表示是否停止迭代,当赋值为false则停止
    
    //        enum {
    //        ALAssetsGroupLibrary        = (1 << 0),
    //        ALAssetsGroupAlbum          = (1 << 1),
    //        ALAssetsGroupEvent          = (1 << 2),
    //        ALAssetsGroupFaces          = (1 << 3),
    //        ALAssetsGroupSavedPhotos    = (1 << 4),
    //        ALAssetsGroupPhotoStream    = (1 << 5),
    //        ALAssetsGroupAll            = 0xFFFFFFFF,
    //        };
    
    [_library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
    NSLog(@"group name:%@",[group valueForProperty:ALAssetsGroupPropertyName]);
    } failureBlock:^(NSError *error) {
    
    }];
    
    //保存图片到系统默认的相册中,使用nsdata的形式,并返回照片的url地址
    [_library writeImageDataToSavedPhotosAlbum:nil metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
    
    }];
    //保存图片到系统默认的相册中,使用cgimageref的形式,并返回照片的url地址
    [_library writeImageToSavedPhotosAlbum:nil metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
    
    }];
    //保存图片到系统默认的相册中,使用cgimageref的形式,并且选择图片以什么旋转方向的形式保存,并返回照片的url地址
    
    //        typedef enum {
    //        ALAssetOrientationUp,            // default orientation
    //        ALAssetOrientationDown,          // 180 deg rotation
    //        ALAssetOrientationLeft,          // 90 deg CCW
    //        ALAssetOrientationRight,         // 90 deg CW
    //        ALAssetOrientationUpMirrored,    // as above but image mirrored along other axis. horizontal flip
    //        ALAssetOrientationDownMirrored,  // horizontal flip
    //        ALAssetOrientationLeftMirrored,  // vertical flip
    //        ALAssetOrientationRightMirrored, // vertical flip
    //        } ALAssetOrientation;
    
    UIImage* image = [UIImage imageNamed:@"test.png"];
    [_library writeImageToSavedPhotosAlbum:[image CGImage] orientation:ALAssetOrientationLeft completionBlock:^(NSURL *assetURL, NSError *error) {
    NSLog(@"save image:%@",assetURL);
    }];
  • 相关阅读:
    【Hadoop】MapReduce自定义分区Partition输出各运营商的手机号码
    【Hadoop】Hadoop的数据压缩方式
    【Java】生成随机的手机号码并输出到文件
    【Java】递归删除目录以及文件
    【Hadoop】单机、伪分布式、完全分布式集群搭建
    【Linux】常用基础命令
    【Web】jquery合并单元格
    【PHP】PHPStorm中文乱码解决方式
    【DataBase】mysql连接错误:Cannot get hostname for your address
    【.NET】Browser Link: Failed to deserialize JSON in Browser Link call
  • 原文地址:https://www.cnblogs.com/Jenaral/p/5369212.html
Copyright © 2011-2022 走看看