iOS中获取系统相册中的图片

作者: 黑黝黝的搬砖王 | 来源:发表于2018-01-11 10:09 被阅读2216次

    一、调起系统相册选择器

    • 1.利用UIImagePickerController从系统自带的App(照片\相机)中获得图片
    • 2.设置代理,遵守代理协议

    注意这个UIImagePickerController类比较特殊,需要遵守两个代理协议

    @interface ViewController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

    • 3.实现代理的方法didFinishPickingMediaWithInfo

    -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker

    -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info

    -(void)showActionSheet
    {
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"选择图片" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
        UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
        UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            NSString *mediaType = AVMediaTypeVideo;
            AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
            if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied){
                //            mAlertView(@"", @"请在'设置'中打开相机权限")
                return;
            }
            
            if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
                //            mAlertView(@"", @"照相机不可用")
                return;
            }
            UIImagePickerController *vc = [[UIImagePickerController alloc] init];
            vc.delegate = self;
            vc.allowsEditing = YES;
            vc.sourceType = UIImagePickerControllerSourceTypeCamera;
            [self presentViewController:vc animated:YES completion:nil];
        }];
        UIAlertAction *action3 = [UIAlertAction actionWithTitle:@"相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            UIImagePickerController *vc = [[UIImagePickerController alloc] init];
            vc.delegate = self;
            vc.allowsEditing = YES;
            vc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            [self presentViewController:vc animated:YES completion:nil];
        }];
        [alert addAction:action1];
        [alert addAction:action2];
        [alert addAction:action3];
        [self presentViewController:alert animated:YES completion:nil];
    }
    
    -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
    {
        [picker dismissViewControllerAnimated:YES completion:nil];
    }
    
    -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
    {
        UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
        [self.senderBtn setBackgroundImage:image forState:UIControlStateNormal];
        //图片在这里压缩一下
        NSData *imageData = UIImageJPEGRepresentation(image, 0.5f);
        if (imageData.length/1024 > 1024*20)
        {
    //        mAlertView(@"温馨提示", @"请重新选择一张不超过20M的图片");
        }
        else
        {
    //        _imageType = [NSData typeForImageData:imageData];
    //        _imageBase64 = [imageData base64EncodedString];
        }
        [picker dismissViewControllerAnimated:YES completion:nil];
    
    }
    

    二、获取系统相册所有图片

    • 导入头文件#import <Photos/Photos.h>
    • PHAsset : 一个资源, 比如一张图片\一段视频
    • PHAssetCollection : 一个相簿
    • PHImageManager 图片管理者,是单例,发送请求才能从asset获取图片
    • PHImageRequestOptions图片请求选项

    注意:这个类是iOS8开始推广,iOS9开始废弃之前的方法
    系统适配iOS8之前,用下面这个库里面的API
    import <AssetsLibrary/AssetsLibrary.h>

    • 1.获得相簿全部原图
    - (void)getOriginalImages
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 获得所有的自定义相簿
            PHFetchResult<PHAssetCollection *> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
            // 遍历所有的自定义相簿
            for (PHAssetCollection *assetCollection in assetCollections) {
                [self enumerateAssetsInAssetCollection:assetCollection original:YES];
            }
            
            // 获得相机胶卷
            PHAssetCollection *cameraRoll = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil].lastObject;
            // 遍历相机胶卷,获取大图
            [self enumerateAssetsInAssetCollection:cameraRoll original:YES];
        });
    }
    
    • 2.获得相簿中全部缩略图
    - (void)getThumbnailImages
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 获得所有的自定义相簿
            PHFetchResult<PHAssetCollection *> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
            // 遍历所有的自定义相簿
            for (PHAssetCollection *assetCollection in assetCollections) {
                [self enumerateAssetsInAssetCollection:assetCollection original:NO];
            }
            // 获得相机胶卷
            PHAssetCollection *cameraRoll = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil].lastObject;
            [self enumerateAssetsInAssetCollection:cameraRoll original:NO];
        });
    }
    
    • 3.遍历相册
     *  遍历相簿中的全部图片
     *  @param assetCollection 相簿
     *  @param original        是否要原图
     */
    - (void)enumerateAssetsInAssetCollection:(PHAssetCollection *)assetCollection original:(BOOL)original
    {
        NSLog(@"相簿名:%@", assetCollection.localizedTitle);
        
        PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
        options.resizeMode = PHImageRequestOptionsResizeModeFast;
        // 同步获得图片, 只会返回1张图片
        options.synchronous = YES;
        
        // 获得某个相簿中的所有PHAsset对象
        PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
        for (PHAsset *asset in assets) {
            // 是否要原图
            CGSize size = original ? CGSizeMake(asset.pixelWidth, asset.pixelHeight) : CGSizeZero;
            
            // 从asset中获得图片
            __weak typeof(self) weakSelf = self;
            [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                NSLog(@"%@", result);
                original ? [weakSelf.photoArray addObject:result] : [weakSelf.photoArray addObject:result];
            }];
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf.showPhotoCollectionView reloadData];
            });
        }
    }
    

    特别注意:
    (1).获取全部原图或者全部缩略图时,运行的代码要放在 全局并行队列中


    910C933E-8719-4ABD-A24B-547129ED7F7A.png

    (2).遍历相册获取到所有图片后再主线程中刷新列表


    419D68CD-976F-4F16-B09F-9130240FAF95.png

    (3).经过本人测试,放在全局并行队列之后获取相册图片速度都是秒级可以完成,不会阻塞主线程。

    上面的Demo链接

    这个简单的需求是因为项目中只要选择一张图片,并且不需要展现图片详情,直接选择,后续会补上多张图片选择、展示的事例。

    相关文章

      网友评论

        本文标题:iOS中获取系统相册中的图片

        本文链接:https://www.haomeiwen.com/subject/ovkznxtx.html