iOS存取照片到自定义相册以及从相册取照片

来源:互联网 发布:扔玻璃珠算法 编辑:程序博客网 时间:2024/06/13 17:34

因为iOS系统相册权限及照片显示的问题,所以没法像android一样直接在某个路径下创建文件夹存储照片,并利用名字来取照片。iOS实现存储照片到自定义相册,其实是先把图片存到系统相册,然后创建一个相薄,在从系统相册中取出那张照片添加到自定义的相薄中。

使用框架

1.AssetsLibrary,这个框架在iOS9之后废弃掉了,所以建议大家用第二种方法
2.Photos,这个从iOS8之后就可以使用,取代了AssetsLibrary

框架中的类与参数介绍

· PHAssetCollection 图片的集合,其实就是指的一个相册,不管是系统的还是自定义的
· PHFetchResult 表示该相册中的资源的集合
· PHAsset 表示这个相册中的某一个资源,可以是图片或者视频,上面的PHFetchResult其实就相当于一个数组,而PHAsset就相当于数组中的子元素
· localIdentifier PHObject中的一个参数,某个对象的唯一标识符,想要找到相册中存取的某张照片,可以通过这个id遍历查找,其实就像手机的UDID,唯一标识你这个手机

代码块

保存照片到自定义相册

//MARK: -将图片保存到自定义相册中-(void)saveImageToCustomAblum{    //将图片保存到系统的相册    PHFetchResult<PHAsset *> *assets = [self saveImageWithPhotos];    if (assets == nil)    {        //自已封装一个debug模式下的log,不然到时候上线还要注释掉        DLog(@"保存失败");        return;    }           //创建自定义相册(自己命名,如果没有则创建)           PHAssetCollection *assetCollection = [self getAssetCollectionAppNameAndCreate];    if (assetCollection == nil) {        DLog(@"相册创建失败");        return;    }        //将刚才保存到系统相册的图片添加到自定义相册中     NSError *error = nil;    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{        //选取自定义相册进行操作        PHAssetCollectionChangeRequest *collectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];        //插入图片到自定义相册        PHFetchResult<PHAsset *> *assetCount = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];        [collectionChangeRequest insertAssets:assets atIndexes:[NSIndexSet indexSetWithIndex:assetCount.count]];        //取出保存的那个对象(图片)        PHAsset *ass = [assets objectAtIndex:0];        NSString *aaa = [ass localIdentifier];        //暂存一下图片的id,后面需要通过id取出照片(你可以存一个数组,也可以取出多张照片,这里就说一下取出单张的)        [[NSUserDefaults standardUserDefaults] setObject:aaa forKey:kAssetID];    } error:&error];       if (error) {        DLog(@"保存失败");        return;    }    DLog(@"保存成功");}

1.保存图片到系统的相册中,返回结果是保存成功后的图片集合

-(PHFetchResult<PHAsset *> *)saveImageWithPhotos{    __block NSString *createdAssetID = nil;        NSError *error = nil;    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{        //获取图片的id        createdAssetID = [PHAssetChangeRequest             creationRequestForAssetFromImage:_imm].placeholderForCreatedAsset.localIdentifier;    } error:&error];    if (error) {        return nil;    }    //获取保存到系统相册成功后的 asset 对象集合(一张图片也是返回一个集合)    PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[createdAssetID] options:nil];    return assets;}

2.判断有没有拥有与你设定的名字同名的自定义相册(如果没有则创建)

-(PHAssetCollection *)getAssetCollectionAppNameAndCreate{    //设置你想要创建的相册的名字    NSString *title = @"我的新建相册";    //获取与要创建的相册同名的自定义相册    PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];    for (PHAssetCollection *collection in collections) {        //遍历        if ([collection.localizedTitle isEqualToString:title]) {            //找到了同名的自定义相册,返回            return collection;        }    }    //程序走到这,说明没有找到自定义的相册,需要创建    NSError *error = nil;    __block NSString *createID = nil; //用来获取创建好的相册    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{        //发起了创建新相册的请求,并拿到相册的id,当前并没有创建成功,待创建成功后,通过id来获取创建好的自定义相册        PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];        createID = request.placeholderForCreatedAssetCollection.localIdentifier;    } error:&error];    if (error) {        DLog(@"创建失败");        return nil;    }else{        DLog(@"创建成功");        [[NSUserDefaults standardUserDefaults] setObject:createID forKey:kAlbumID];        //通过id获取创建完成的相册        return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createID] options:nil].firstObject;    }   }

从相册中取照片

1.先通过你自定义的相册的名字,找到这个PHAssetCollection
2.找到你的PHAssetCollection(自定义相册)之后,通过遍历相册集合,根据id值判断是否有匹配的图片

//通过 相薄名字查找新建相册var albumColl = PHAssetCollection()let collections:PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.Album, subtype: .AlbumRegular, options: nil)for j in 0..<collections.count {    let collection:PHAssetCollection = collections[j] as! PHAssetCollection    if collection.localizedTitle == "我的新建相册" {        //找到了同名的自定义相册,返回        albumColl = collection        break    }}let picAssets:PHFetchResult = PHAsset.fetchAssetsInAssetCollection(albumColl, options: nil)//遍历assets集合,找到id值一样的图片取出来for i in 0..<picAssets.count {    let asset:PHAsset = picAssets[i] as! PHAsset    if asset.localIdentifier == (NSUserDefaults.standardUserDefaults().objectForKey("assetId") as! String)! {        PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: PHImageManagerMaximumSize, contentMode: .AspectFit, options: nil, resultHandler: { (result: UIImage?, dictionry: Dictionary?) in            //根据result取出这张照片                        if result != nil && result != NSNull() {                self.albumIma = result!            } else {                self.albumIma = UIImage.init(named: "pic_loading")!            }        })    }}

注意

自定义相册里面的照片,其实相当于系统相册中图片的一个影子,系统相册里的图片没了,影子也就不存在了。因为每次拍照存放照片,实际上先存放到系统相册,然后从系统相册插入过去的;再删除照片的时候,系统相册的删除了,两个相册的照片就全没了,但是自定义相册里的照片删除,系统相册的照片则无影响


多说一句,假如你把每次拍照的图片都存放到一个本地文件或者小型的SQL数据库里面,进行持久化存储了,那么一定要在程序每次进入活跃状态的时候,检测自定义相册中的图片和数据库中的是否匹配,不匹配就删除本地多余的照片,这样才能做到实时对应。至于检测匹配就不要用两个for in嵌套了(时间复杂度O(m*n)),通过两个哈希序列进行比较是比较简单的做法(时间复杂度O(m+n))。

1 0