当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS中读取照片库及保存图片或视频到照片库的要点解析

iOS中读取照片库及保存图片或视频到照片库的要点解析

2019年07月24日  | 移动技术网IT编程  | 我要评论

王欣谣,小q,众诚远马科技

读取照片库photolibrary
ios中如果我们只有一次读取一张图片或者一个视频(或拍一张照片/视频)的需求,那么我们用 uiimagepickercontroller 就可以搞定。但是很多时候我们需要一次性从photolibrary读取多个照片或者视频,这时候我们就需要另辟蹊径了,好在apple为我们提供了相应的接口。
在开始coding之前我们想要认识几个类:
alassetslibrary:代表整个photolibrary,我们可以生成一个它的实例对象,这个实例对象就相当于是照片库的句柄。
alassetsgroup:照片库的分组,我们可以通过alassetslibrary的实例获取所有的分组的句柄。
alasset:一个alasset的实例代表一个资产,也就是一个photo或者video,我们可以通过他的实例获取对应的subnail或者原图等等。
还需要了解的一个东东就是blocks,apple在ios 4.0以后大量出现了这玩意儿,有使用越来越广的意思,不过这玩意儿确实好用。关于这玩意儿的内容我在这里不多讲,关注我的博客我会细讲。
对于本文的需求,我们读取group和每个asset都是异步的,但是我们现在用blocks我们可以在一个函数里面搞定。所以blocks确实很方便。
下面直接看代码吧:

复制代码 代码如下:

alassetslibrary *assetslibrary = [[alassetslibrary alloc]init];//生成整个photolibrary句柄的实例   
nsmutablearray *mediaarray = [[nsmutablearray alloc]init];//存放media的数组   
    [assetslibrary enumerategroupswithtypes:alassetsgroupall usingblock:^(alassetsgroup *group, bool *stop) {//获取所有group   
        [group enumerateassetsusingblock:^(alasset *result, nsuinteger index, bool *stop) {//从group里面   
            nsstring* assettype = [result valueforproperty:alassetpropertytype];   
            if ([assettype isequaltostring:alassettypephoto]) {   
                nslog(@"photo");   
            }else if([assettype isequaltostring:alassettypevideo]){   
                nslog(@"video");   
            }else if([assettype isequaltostring:alassettypeunknown]){   
                nslog(@"unknow assettype");   
            }   
               
            nsdictionary *asseturls = [result valueforproperty:alassetpropertyurls];   
            nsuinteger assetcounter = 0;   
            for (nsstring *asseturlkey in asseturls) {   
                nslog(@"asset url %lu = %@",(unsigned long)assetcounter,[asseturls objectforkey:asseturlkey]);   
            }   
               
            nslog(@"representation size = %lld",[[result defaultrepresentation]size]);   
        }];   
    } failureblock:^(nserror *error) {   
        nslog(@"enumerate the asset groups failed.");   
    }];  

保存图片或视频到photolibrary
时文件然后,然后通过临时文件的路径去转存到photo library。
我们直接来看相应的api:

复制代码 代码如下:

// these methods can be used to add photos or videos to the saved photos album. 
 
// with a uiimage, the api user can use -[uiimage cgimage] to get a cgimageref, and cast -[uiimage imageorientation] to alassetorientation. 
- (void)writeimagetosavedphotosalbum:(cgimageref)imageref orientation:(alassetorientation)orientation completionblock:(alassetslibrarywriteimagecompletionblock)completionblock; 
 
// the api user will have to specify the orientation key in the metadata dictionary to preserve the orientation of the image 
- (void)writeimagetosavedphotosalbum:(cgimageref)imageref metadata:(nsdictionary *)metadata completionblock:(alassetslibrarywriteimagecompletionblock)completionblock __osx_available_starting(__mac_na,__iphone_4_1); 
 
// if there is a conflict between the metadata in the image data and the metadata dictionary, the image data metadata values will be overwritten 
- (void)writeimagedatatosavedphotosalbum:(nsdata *)imagedata metadata:(nsdictionary *)metadata completionblock:(alassetslibrarywriteimagecompletionblock)completionblock __osx_available_starting(__mac_na,__iphone_4_1); 
 
- (void)writevideoatpathtosavedphotosalbum:(nsurl *)videopathurl completionblock:(alassetslibrarywritevideocompletionblock)completionblock; 

前三个都是存图片的,通过参数我们可以发现,第一个使用了我们传进去的方向,第二个可以通过传入image的metadata保留image的metadata,前两个都是把图片转成 cgimageref 再保存,第三个是传入nsdata所以可以完整保留image的信息,同时也有metadata传进去,如果image自带的信息与metadata冲突那metadata会覆盖图片本身所带的metadata。
最后一个是存储视频的api,可以看到参数是一个nsurl,这个只要穿一个本地临时文件的file url 就好了。
存储图片根据你的需求选择适当的api,比如我们获取到的是uiimage的实例,那么我们用第一个或者第二个比较方便,如果我们从本地临时文件读取image的数据那么我们直接用第三个就比较方便。
下面来一段简单的代码:
复制代码 代码如下:

- (void)saveimage:(uiimage*)image{ 
    alassetslibrary *assetslibrary = [[alassetslibrary alloc]init]; 
    [assetslibrary writeimagetosavedphotosalbum:[image cgimage] orientation:(alassetorientation)image.imageorientation completionblock:^(nsurl *asseturl, nserror *error) { 
        if (error) { 
            nslog(@"save image fail:%@",error); 
        }else{ 
            nslog(@"save image succeed."); 
        } 
    }]; 


保存video就麻烦点了,你需要先把video写入本地文件然后,获取到本地临时文件的路径,然后调用上面的第四个api写入photo library。
关于写入临时文件,我之前写过一篇关于文件读写的文章,可以去看看。
我这里奉上一个把工程资源库的video写入photo library的demo,这样你就可以把video导入模拟器了,方便有些时候测试。
主要代码如下:
复制代码 代码如下:

- (void)save:(nsstring*)urlstring{ 
    alassetslibrary *library = [[alassetslibrary alloc] init]; 
    [library writevideoatpathtosavedphotosalbum:[nsurl fileurlwithpath:urlstring] 
                                completionblock:^(nsurl *asseturl, nserror *error) { 
                                    if (error) { 
                                        nslog(@"save video fail:%@",error); 
                                    } else { 
                                        nslog(@"save video succeed."); 
                                    } 
                                }]; 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网