之前没做过这一块的,今天也是刚接触,上网查了一下主要是两个库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 .framework
和Photos.framework
全文重点来了Github地址在这里
但是在使用AssetsLibrary
获取所有图片的时候会有很明显的卡顿,如果需要支持iOS 8之前的话,可以参考iOS 开发之照片框架详解提到的索引加载
- 踩到的坑
- 使用下面这个方法获取图片,会得到多次,首次加载的时候,会先得到一个相对模糊的图片,随后会再次得到一张清晰的图像,但是如果我要一开始就要得到是高清的图像呢?
//获取图片
+ (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);
- 获取相册中的图片转成
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
请保持转载后文章内容的完整,以及文章出处。本人保留所有版权相关权利。