2016-01-25 20:54:03 LBY5211ABC 阅读数 705

遍历iOS相册

主题 《iOS开发》 by evan

一.ALAssetsLibrary介绍

ALAssetsLibrary 提供了访问iOS设备下”照片”应用下所有照片和视频的接口;

  1. 从 ALAssetsLibrary 中可读取所有的相册数据,即 ALAssetsGroup 对象列表;
  2. 从每个 ALAssetsGroup 中可获取到其中包含的照片或视频列表,即 ALAsset 对象列表;
  3. 每个 ALAsset 可能有多个representations表示,即 ALAssetRepresentation 对象,使用其 defaultRepresentation 方法可获得其默认representations,使用[asset valueForProperty: ALAssetPropertyRepresentations ]可获取其所有representations的 UTI 数组。
  4. 从ALAsset对象可获取缩略图 thumbnail 或 aspectRatioThumbnail ;
  5. 从 ALAssetRepresentation 对象可获取全尺寸图片( fullResolutionImage ),全屏图片( fullScreenImage )及图片的各种属性: orientation , dimensions , scale , url , metadata 等。

其层次关系为 ALAssetsLibrary -> ALAssetsGroup -> ALAsset -> ALAssetRepresentation

注意:

  1. The lifetimes of objects you get back from a library instance are tied to the lifetime of the library instance.
    通过ALAssetsLibrary对象获取的其他对象只在该ALAssetsLibrary对象生命期内有效,若ALAssetsLibrary对象被销毁,则其他从它获取的对象将不能被访问,否则有会错误。

    invalid attempt to access ALAssetPrivate past the lifetime of its owning ALAssetsLibrary

  2. ALAssetRepresentation的 metadata 方法很慢,我在iPhone4 iOS5.1.1中测试,此方法返回需要40-50ms,所以获取图片的个各种属性尽量直接从ALAssetRepresentation中获取,不要读取metadata。 这里 给出了一个此方法占用内存过多的解释,调用多次也确实很容易会memory warning,或许也能解析其为什么很慢吧。

    The method [representation metadata] returns an autoreleased object and possibly creates more autoreleased objects when it executes. All these instances are added to the autorelease pool, waiting to be finally released (and their memory freed) when the ARP gets the chance to drain itself.

  3. 系统”相册”程序显示的图片是 fullScreenImage ,而不是 fullResolutionImage ,fullResolutionImage尺寸太大,在手机端显示推荐用fullScreenImage。 fullScreenImage已被调整过方向,可直接使用,即
    [UIImage imageWithCGImage:representation.fullScreenImage];
    使用fullResolutionImage要自己调整方法和scale,即
    [UIImage imageWithCGImage:representation.fullResolutionImage scale:representation.scale orientation:representation.orientation];

二.创建 ALAssetsLibrary对象

使用ALAssetsLibrary之前需导入头文件和AssetsLibrary.framework。

  #import 


  ...
  ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc]init];
  ...

三.遍历Assets Group

  1. 使用 enumerateGroupsWithTypes:usingBlock:failureBlock: 方法可遍历assets group;

  2. 此方法为异步执行,若之前未被授权过,此方法会向用户请求访问数据的权限;若用户拒绝授权或其他错误则会执行failureBlock;

  3. 如果用户关掉了位置服务(Location Services,在设置->通用中),返回的错误为 ALAssetsLibraryAccessGloballyDeniedError 。

  4. enumerationBlock和failureBlock与在调用此方法的线程内执行,若要在背景线程进行遍历,可将遍历代码放入GCD或NSOperation中。

 [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        if (!group) {
            [tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
        }else{
            [groupsArray addObject:group];
            ...
        }

    } failureBlock:^(NSError *error) {
        NSLog(@"error:%@",error);
    }];

四.遍历Assets Group中的Assets

  1. 使用 enumerateAssetsUsingBlock: 方法或者其他变体方法可遍历ALAssetsGroup中的所有ALAsset;

  2. 可通过 setAssetsFilter: 设置过滤器( ALssetsFilter )使enumerateAssetsUsingBlock:只返回特定类型asset,而 numberOfAssets 只返回特定类型asset的数量。
    可以设置只显示Photo( allPhotos ),只显示Video( allVideos ),或显示全部( allAssets )。

  3. enumerateAssetsUsingBlock:为同步方法,只有所有Asset遍历完才返回。所以需要将遍历代码放入背景线程,防止阻塞UI线程。

[assetsGroup setAssetsFilter:[ALAssetsFilter allPhotos]];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [assetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
            if (!result) {
                [tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
            }else{
                [assetsArray addObject:result];
                ...
            }
        }];
    });

五.根据url获取asset

使用ALAssetsLibrary的 assetForURL:resultBlock:failureBlock: 方法,可根据之前从ALAssetRepresentation中获取的url重新获取ALAsset对象,此方法同enumerateGroupsWithTypes:usingBlock:failureBlock:一样为异步方法。

六.获取Assets的各种属性

  1. 相册封面图片 [assetsGroup posterImage ];

  2. 照片url[[[asset defaultRepresentation] url] absoluteString];

  3. 照片缩略图
    [asset thumbnail];
    [asset aspectRatioThumbnail];

  4. 照片全尺寸图
    [[asset defaultRepresentation] fullResolutionImage];

  5. 照片全屏图
    [[asset defaultRepresentation] fullScreenImage];

  6. 照片创建时间
    [asset valueForProperty:ALAssetPropertyDate];

  7. 照片拍摄位置(可能为nil)
    [asset valueForProperty:ALAssetPropertyLocation];

  8. 照片尺寸
    [[asset defaultRepresentation] dimensions];

    从小到大依次为 fullResolutionImage > fullScreenImage -> thumbnail -> aspectRatioThumbnail

七.获取原图

    Byte *fileBuffer = (Byte*)malloc((long)representation.size);
    NSUInteger bufferSize = [representation getBytes:fileBuffer fromOffset:0 length:(long)representation.size error:nil];
    data = [NSData dataWithBytesNoCopy:fileBuffer length:bufferSize freeWhenDone:YES];
    CGSize size = representation.dimensions;
    image = [[JNBLImageStoreManager instance] storeData:data withType:type referenceURL:referenceURL];
2017-12-04 17:50:29 yanhsheng304 阅读数 1975

问题如图
这里写图片描述

该问题是因为设置了

if (@available(iOS 11, *)) {
        UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }

引起的。

解决方案
在弹出系统相册前加入

 if (@available(iOS 11, *)) {
        UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
    }
 UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
    ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    ipc.delegate = self;
    ipc.allowsEditing = YES;
    if (@available(iOS 11, *)) {
        UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
    }
    [self presentViewController:ipc animated:YES completion:nil];

在 - (void)imagePickerController:(UIImagePickerController )picker didFinishPickingMediaWithInfo:(NSDictionary

if (@available(iOS 11, *)) {
        UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }

就解决了!!!

2017-12-22 13:10:34 qq_36905061 阅读数 1031

问题描述:在需要传照片的页面,通常是开放相册和相机两个选取照片的入口.但通常都是使用一个imagepickercontroller对象来实现调取相册相机.在iOS11之前,这么做是没有问题的.但是需要切换一下sourceType这个属性的值.在iOS11之后,相机相册要是使用同一个imagepickercontroller会出现问题.先打开相机,再打开相册的时候,相册页面的navigation的取消按钮等都消失了.


解决办法,其实很简单,相册和相机使用独立的imagepickercontroller对象来调取.


imagepickercontroller展示相册的时候,需要选择图片,这时如果是快速点击同一张图片,那么didfinish的代理方法就会连续调用,虽然回调的都是同一张图片,但是如果遇到将回调的图片放到数组中的情况时就会出问题,这个应该不是代码的原因,尽量避免用数组盛放选择的图片。

2017-10-10 10:58:46 q1194259339 阅读数 6987

背景:升级iOS11后,相册权限发生变化。

变化:

相册权限需要在info.plist—Property List文件中添加NSPhotoLibraryUsageDescription键值对,描述文字不能为空。

iOS11之前:访问相册和存储照片到相册(读写权限),需要用户授权,需要添加NSPhotoLibraryUsageDescription。

iOS11之后:默认开启访问相册权限(读权限),无需用户授权,无需添加NSPhotoLibraryUsageDescription,适配iOS11之前的还是需要加的。
添加图片到相册(写权限),需要用户授权,需要添加NSPhotoLibraryAddUsageDescription

总结:iOS11之后如果需要写入权限需要添加NSPhotoLibraryAddUsageDescription字段。

附:

NSPhotoLibraryUsageDescription:

Property List:

Privacy - Photo Library Usage Description

Source Code:

<key>NSPhotoLibraryUsageDescription</key>

<string>是否允许此APP使用相册?</string>


NSPhotoLibraryAddUsageDescription :

Property List:

Privacy - Photo Library Additions Usage Description

Source Code:

<key>NSPhotoLibraryAddUsageDescription</key>

<string>是否允许此APP保存图片到相册?</string>


2015-09-10 20:20:06 ETmanwenhan 阅读数 1277
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
    imagePickerController.delegate = self;
    imagePickerController.allowsEditing = NO;
    imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    imagePickerController.mediaTypes =[NSArray arrayWithObjects: (NSString *)kUTTypeMovie, nil];
    //imagePickerController.videoQuality = UIImagePickerControllerQualityType640x480;
    imagePickerController.videoQuality=UIImagePickerControllerQualityTypeMedium;
    
    [self presentViewController:imagePickerController animated:YES completion:nil];


#pragma mark - UIImagePickerControllerDelegate
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    
    if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:(NSString*)kUTTypeMovie]) {
        
        NSString *videoName = [dateFormatter2 stringFromDate:[NSDate date]];
        _importVideoPath = [NSHomeDirectory() stringByAppendingPathComponent:[_videoPath stringByAppendingString:
                            [NSString stringWithFormat:@"%@.mov",videoName]]];
        NSLog(@"_importVideoPath:%@",_importVideoPath);
        NSError *error;
        NSData *videoData = [NSData dataWithContentsOfURL:[info objectForKey:UIImagePickerControllerMediaURL]];
        
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL success = [fileManager fileExistsAtPath:_importVideoPath];
        
        if(success) {
            NSLog(@"found a video and removeItemAtPath");
            success = [fileManager removeItemAtPath:_importVideoPath error:&error];
        }
        BOOL writeToFile=[videoData writeToFile:_importVideoPath atomically:NO];
        NSLog(@"导入成功 writeToFile:%@",writeToFile==YES?@"YES":@"NO");
        
        [picker dismissViewControllerAnimated:YES completion:^{
            //将视频信息插入数据库
            [self getVideoInfo:_importVideoPath];
            long long size=[DiskSpaceTool fileSizeAtPath:_importVideoPath];
            //插入数据库
            [dbManager insertWithTable:kLocalVideosTableName value_map:
             @{kLocalVideos_Name:[NSString stringWithFormat:@"%@.mov",videoName],
               kLocalVideos_OriginPath:_importVideoPath,
               kLocalVideos_LengthString:_lengthString,
               kLocalVideos_Length:[NSString stringWithFormat:@"%d",_length],
               kLocalVideos_Size:[NSString stringWithFormat:@"%lld",size],
               kLocalVideos_CoverPath:@"",
               kLocalVideos_CoverTime:@"0",
               kLocalVideos_CreateDate:videoName,
               kLocalVideos_UploadSeccuss:@"0"}];
            
            //刷新
            [self refreshTableView];

        }];
    }
    
    
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [picker dismissViewControllerAnimated:YES completion:nil];
}


iOS 相册权限

阅读数 605

ios监测相册变化

阅读数 881

ios监测相册变化

博文 来自: yw1990128

ios向上取整

阅读数 12024

ios向上取整 ceilf()

博文 来自: aini9080
没有更多推荐了,返回首页