iOS获取相册中的所有图片,以及申请权限,总结自己踩到的坑

iOS,相机,相册

Posted by Karim on September 22, 2017

之前没做过这一块的,今天也是刚接触,上网查了一下主要是两个库iOS 8之前需要使用AssetsLibrary .framework,iOS 8之后使用Photos.framework 想看详细讲解的,可以直接看iOS 开发之照片框架详解 Photos参考了这里获取系统相册的所有照片

在iOS 8以后,申请相册权限是可以得到回调的:

[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
            if (request_block)
            {
                if (status == PHAuthorizationStatusAuthorized) {
                    request_block(YES);
                }else{
                    request_block(NO);
                }
                
            }
        }];
      
    }];

申请摄像头权限:

[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
            if (request_block)
            {
                    request_block(granted);
            }
        }];
    }];

其实都是不太复杂的东西,网上看下就懂了,获取系统所有图片的时候得每个都转UIImage这点很不好用,我分别封装了一下AssetsLibrary .frameworkPhotos.framework

全文重点来了Github地址在这里

但是在使用AssetsLibrary获取所有图片的时候会有很明显的卡顿,如果需要支持iOS 8之前的话,可以参考iOS 开发之照片框架详解提到的索引加载

  • 踩到的坑
    1. 使用下面这个方法获取图片,会得到多次,首次加载的时候,会先得到一个相对模糊的图片,随后会再次得到一张清晰的图像,但是如果我要一开始就要得到是高清的图像呢?
//获取图片
+ (void)accessToImageAccordingToTheAsset:(PHAsset *)asset size:(CGSize)size resizeMode:(PHImageRequestOptionsResizeMode)resizeMode completion:(void(^)(UIImage *image,NSDictionary *info))completion
{
    static PHImageRequestID requestID = -2;
    
    CGFloat scale = [UIScreen mainScreen].scale;
    CGFloat width = MIN([UIScreen mainScreen].bounds.size.width, 500);
    if (requestID >= 1 && size.width / width == scale) {
        [[PHCachingImageManager defaultManager] cancelImageRequest:requestID];
    }
    PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
    option.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
    option.resizeMode = resizeMode;
 
    requestID = [[PHCachingImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
        dispatch_async(dispatch_get_main_queue(), ^{
            completion(result,info);
        });
    }];
    
}

原因是因为将option.deliveryMode 设置成了PHImageRequestOptionsDeliveryModeOpportunistic, 你以为只要把option.deliveryMode 设置成了PHImageRequestOptionsDeliveryModeFastFormat就可以了吗? 这时候还要设置option.synchronous = YES; 但是这样设置后,获取图片会变成同步操作,如果直接获取相册中的所有照片,会造成卡顿。

typedef NS_ENUM(NSInteger, PHImageRequestOptionsDeliveryMode) {
    PHImageRequestOptionsDeliveryModeOpportunistic = 0, // client may get several image results when the call is asynchronous or will get one result when the call is synchronous
    PHImageRequestOptionsDeliveryModeHighQualityFormat = 1, // client will get one result only and it will be as asked or better than asked (sync requests are automatically processed this way regardless of the specified mode)
    PHImageRequestOptionsDeliveryModeFastFormat = 2 // client will get one result only and it may be degraded
} PHOTOS_ENUM_AVAILABLE_IOS_TVOS(8_0, 10_0);
  1. 获取相册中的图片转成NSData得到nil 我遇到的场景是: 在获取了相册图片后,需要将UIImage转成NSData,但是会有少部分图片,使用下面的方法转成NSData会得到nil的情况
NSData *jpegData = UIImageJPEGRepresentation(image, 0.2);
NSData *pngData = UIImagePNGRepresentation(image);

这种情况,可以通过重新绘制UIImage:

NSData *jpegData = UIImageJPEGRepresentation(image, 0.2);
  if (jpegData == nil) {
jpegData = image.generateJPEGRepresentation;
    if (jpegData == nil) {
return ;
  }
}

@implementation UIImage (FIDExtra)

- (NSData *)generateJPEGRepresentation
{
    UIImage *newImage = [self copyOriginalImage];
    NSData *newData = UIImageJPEGRepresentation(newImage, 0.2);
    return newData;
}

- (UIImage *)copyOriginalImage
{
    UIGraphicsBeginImageContext(self.size);
    [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

@end

请保持转载后文章内容的完整,以及文章出处。本人保留所有版权相关权利。

分享到: