美文网首页iOS开发 那些我踩过的坑
TZImagePickerController 拍照返回的照片错

TZImagePickerController 拍照返回的照片错

作者: Serius | 来源:发表于2018-04-24 23:31 被阅读0次

        项目中需要用到相册,自己封装比较耗时,所以选择了现成的第三方SDK,选来选去(其实也没怎么选)最终选择了TZImagePickerController(以下简称TZImage)。很舒服的一个开源相册,功能还是很强大,在此膜拜一下作者。

        那么说一说我在使用时遇到的一个小问题,如题:

        bug:当系统相册中出现“来自未来的照片”(相册中有照片的存储时间是未来的某个时间,原因暂时未知,可能是用户在拍照时自行修改了iPhone的时间),使用TZImage的拍照功能会出现最终得到的照片不是拍照获得的照片问题。(有点拗口,应该能理解吧)

        问题原因(想看解决方法的同学们可以跳过):TZImage拍照完成之后,会将照片按照当前拍摄时间存入本地相册,然后更新相册,再从相册中取出当前排序的第一张照片返回给我们。而一般来说,相册的排序都是按照时间来排的,不论你是选择正序还是倒序,所以在正常情况下这样做是毫无问题的。但就是有时候是不正常的。就像我上面描述所说的:系统相册中出现来自未来的照片,这种情况下,TZImage拍照后获得的照片永远都是相册中的第一张照片。然而我们拍摄得到的照片是当前时间,肯定不会被放在相册的第一张了,也就出现了所拍不所得的问题。(很尴尬)

        既然发现的问题的原因,那么解决起来就方便多了。先来说说我的思路,其实这个问题不算很难解决,我能想到3种解决方法。(原谅我这个菜鸡就这点水平)

        1、在TZImage拍摄完照片的代理中取到当前拍摄的照片,使用block或者代理传递到我们需要的地方,跳过存储和更新相册的过程。

        这种方案简单暴力,解决起来应该是最快的方式。可是对于后续的需求就会造成不便,我们知道在相机的回调中通过此方法获得的照片是原图

    所以对于一些诸如头像设置之类的不需要图片质量那么大的情况下,原图会造成一些不必要的流量操作,网络不好的话用户体验也会受到一定影响。当然我们可以在这里就对图片进行压缩处理,但是这种处理方式显然不是最好的。

        2、在TZImage存储照片的时候,对存储的时间进行调整。

        这种处理方式也很简单,而且无需更多的操作,只是简单的修改一下照片的时间属性。

    只需要在这里将[NSDate date]改成一个相对靠后的时间,你不是来自未来的照片吗,我让你知道什么是未来,设置一个2100年,什么?还不够。那就2200年,总之我就是要我拍摄的照片放在相册的第一个,怎么说?

    皮一下很舒服。好了,言归正传,这种处理方式显然也是有问题的,到时候因为一个APP导致手机里一堆搞不清楚时间的照片,就皮不起来了。

        3、也是我目前能想到的最好的解决方式。当照片存储完成之后,通过照片的localIdentifier获取到照片的PHAsset(iOS 8之前获取ALAsset),再通过PHAsset/ALAsset,获取到TZAssetModel(TZImage自己的图片对象),接着在更新相册的方法中,把我们刚才获取到的Model传进来(推荐block),不再使用TZImage原先的方式取值,把我们自己获取到的Model存入回调数组中,万事大吉。

        说起来很抽象?上代码:

    我将TZImage的savePhotoWithImage:location:completion方法的block进行了调整,新增了一个返回值TZAssetModel *assetModel。在savePhotoWithImage:location:completion方法中将其获取并传递回来:

    - (void)savePhotoWithImage:(UIImage*)image location:(CLLocation*)location completion:(getCurrentPhotos)completion {

        __blockTZAssetModel*model =nil;

        __blockNSString*idStr =nil;

        if (iOS8Later) {

            [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{

                if(iOS9Later) {

                    NSData*data =UIImageJPEGRepresentation(image,0.9);

                    PHAssetResourceCreationOptions *options = [[PHAssetResourceCreationOptions alloc] init];

                    options.shouldMoveFile=YES;

                    PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset];

                    [requestaddResourceWithType:PHAssetResourceTypePhoto data:data options:options];

                    if(location) {

                        request.location= location;

                    }

                    request.creationDate= [NSDatedate];

                    idStr = request.placeholderForCreatedAsset.localIdentifier;

                }else{

                    PHAssetChangeRequest *request = [PHAssetChangeRequest creationRequestForAssetFromImage:image];

                    if(location) {

                        request.location= location;

                    }

                    request.creationDate= [NSDatedate];

                    idStr = request.placeholderForCreatedAsset.localIdentifier;

                }

            }completionHandler:^(BOOLsuccess,NSError*error) {

                dispatch_async(dispatch_get_main_queue(), ^{

                    if(success && completion) {

                        PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[idStr] options:nil];

                        if(result) {

                            PHAsset*asset = [resultlastObject];

                            model = [TZAssetModel modelWithAsset:asset type:TZAssetModelMediaTypePhoto];

                        }

                        completion(model,nil);

                    }elseif(error) {

                        NSLog(@"保存照片出错:%@",error.localizedDescription);

                        if(completion) {

                            completion(model, error);

                        }

                    }

                });

            }];

        }else{

            [self.assetLibrary writeImageToSavedPhotosAlbum:image.CGImage orientation:[self orientationFromImage:image] completionBlock:^(NSURL *assetURL, NSError *error) {

                if(error) {

                    NSLog(@"保存图片失败:%@",error.localizedDescription);

                    if(completion) {

                        completion(model, error);

                    }

                }else{

                    // 多给系统0.5秒的时间,让系统去更新相册数据

                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                        if(completion) {

                            [self.assetLibraryassetForURL:assetURLresultBlock:^(ALAsset*asset) {

                                model = [TZAssetModel modelWithAsset:assetURL type:TZAssetModelMediaTypePhoto];

                                completion(model,nil);

                            }failureBlock:^(NSError*error) {

                                completion(model,nil);

                            }];

                        }

                    });

                }

            }];

        }

    }

    最后,修改排序的方法:

    - (void)reloadPhotoArray:(TZAssetModel*)currentAssetModel {

        TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;

        [[TZImageManager manager] getCameraRollAlbum:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage needFetchAssets:NO completion:^(TZAlbumModel *model) {

            _model= model;

            [[TZImageManager manager] getAssetsFromFetchResult:_model.result completion:^(NSArray *models) {

                [tzImagePickerVchideProgressHUD];

                TZAssetModel*assetModel = currentAssetModel;

                if(tzImagePickerVc.sortAscendingByModificationDate) {

    //                assetModel = [models lastObject];

                    [_modelsaddObject:assetModel];

                }else{

    //                assetModel = [models firstObject];

                    [_modelsinsertObject:assetModelatIndex:0];

                }

                if(tzImagePickerVc.maxImagesCount<=1) {

                    if(tzImagePickerVc.allowCrop) {

                        TZPhotoPreviewController *photoPreviewVc = [[TZPhotoPreviewController alloc] init];

    //                    if (tzImagePickerVc.sortAscendingByModificationDate) {

    //                        photoPreviewVc.currentIndex = _models.count - 1;

    //                    } else {

    //                        photoPreviewVc.currentIndex = 0;

    //                    }

                        photoPreviewVc.currentIndex= [_modelsindexOfObject:assetModel];

                        photoPreviewVc.models=_models;

                        [selfpushPhotoPrevireViewController:photoPreviewVc];

                    }else{

                        [tzImagePickerVc.selectedModelsaddObject:assetModel];

                        [selfdoneButtonClick];

                    }

                    return;

                }

                if(tzImagePickerVc.selectedModels.count< tzImagePickerVc.maxImagesCount) {

                    assetModel.isSelected=YES;

                    [tzImagePickerVc.selectedModelsaddObject:assetModel];

                    [self refreshBottomToolBarStatus];

                }

                _collectionView.hidden=YES;

                [_collectionViewreloadData];

                _shouldScrollToBottom = YES;

                [self scrollCollectionViewToBottom];

            }];

        }];

    }

    原谅我把注释掉的代码也贴上来了,主要是方便以后我查看自己修改的部分。

    PS:第一次写简书。而且技术有限,只能分享一下自己解决问题的思路和最后的成果。大佬们若发现什么问题,请多多指正,我需要你们的鞭策。鞭。。。。策(哪里怪怪的)

    相关文章

      网友评论

        本文标题:TZImagePickerController 拍照返回的照片错

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