iOS开发之获取系统相册中的图片与视频(内带url转换)
#import <AssetsLibrary/AssetsLibrary.h> // 必须导入
// 照片原图路径
#defineKOriginalPhotoImagePath
[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"OriginalPhotoImages"]
// 视频URL路径
#defineKVideoUrlPath
[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES) objectAtIndex:0]stringByAppendingPathComponent:@"VideoURL"]
// caches路径
#defineKCachesPath
[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES) objectAtIndex:0]
//MainViewController
@interfaceMTHMainViewController ()
@property(nonatomic,strong) MTHNextViewController *nextVC;
@property(nonatomic,strong) NSMutableArray *groupArrays;
@property(nonatomic,strong)UIImageView *litimgView;
@end
@implementationMTHMainViewController
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNilbundle:nibBundleOrNil];
if (self) {
// Custominitialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do anyadditional setup after loading the view.
self.navigationItem.title= @"Demo";
self.view.backgroundColor= [UIColor clearColor];
// 初始化
self.groupArrays =[NSMutableArray array];
// 测试BarItem
self.navigationItem.rightBarButtonItem= [[UIBarButtonItem alloc] initWithTitle:@"测试"style:UIBarButtonItemStylePlain target:self action:@selector(testRun)];
// 测试手势
UIPanGestureRecognizer*panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didClickPanGestureRecognizer:)];
[self.navigationController.viewaddGestureRecognizer:panRecognizer];
// 图片或者视频的缩略图显示
self.litimgView = [[UIImageViewalloc] initWithFrame:CGRectMake(100, 200, 120, 120)];
[self.viewaddSubview:_litimgView];
}
- (void)testRun
{
__weakMTHMainViewController *weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
ALAssetsLibraryGroupsEnumerationResultsBlocklistGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) {
if (group !=nil) {
[weakSelf.groupArraysaddObject:group];
} else {
[weakSelf.groupArraysenumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[objenumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if ([resultthumbnail] != nil) {
// 照片
if ([[resultvalueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]){
NSDate *date= [resultvalueForProperty:ALAssetPropertyDate];
UIImage *image =[UIImage imageWithCGImage:[result thumbnail]];
NSString *fileName = [[resultdefaultRepresentation] filename];
NSURL *url = [[resultdefaultRepresentation] url];
int64_t fileSize =[[result defaultRepresentation] size];
NSLog(@"date = %@",date);
NSLog(@"fileName = %@",fileName);
NSLog(@"url = %@",url);
NSLog(@"fileSize = %lld",fileSize);
// UI的更新记得放在主线程,要不然等子线程排队过来都不知道什么年代了,会很慢的
dispatch_async(dispatch_get_main_queue(),^{
self.litimgView.image =image;
});
}
// 视频
else if ([[result valueForProperty:ALAssetPropertyType]isEqualToString:ALAssetTypeVideo] ){
// 和图片方法类似
}
}
}];
}];
}
};
ALAssetsLibraryAccessFailureBlockfailureBlock = ^(NSError *error)
{
NSString *errorMessage =nil;
switch ([errorcode]) {
caseALAssetsLibraryAccessUserDeniedError:
caseALAssetsLibraryAccessGloballyDeniedError:
errorMessage = @"用户拒绝访问相册,请在<隐私>中开启";
break;
default:
errorMessage = @"Reason unknown.";
break;
}
dispatch_async(dispatch_get_main_queue(),^{
UIAlertView *alertView =[[UIAlertView alloc]initWithTitle:@"错误,无法访问!"
message:errorMessage
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil,nil];
[alertView show];
});
};
ALAssetsLibrary*assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibraryenumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:listGroupBlockfailureBlock:failureBlock];
});
}
@但是:
按照上面方法直接取出来的路径是无法传输的,必须自己转化成NSData对象重新写入沙盒路径
viewsource
?
// 将原始图片的URL转化为NSData数据,写入沙盒
- (void)imageWithUrl:(NSURL *)urlwithFileName:(NSString *)fileName
{
// 进这个方法的时候也应该加判断,如果已经转化了的就不要调用这个方法了
// 如何判断已经转化了,通过是否存在文件路径
ALAssetsLibrary*assetLibrary = [[ALAssetsLibrary alloc] init];
// 创建存放原始图的文件夹--->OriginalPhotoImages
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:KOriginalPhotoImagePath]) {
[fileManagercreateDirectoryAtPath:KOriginalPhotoImagePath withIntermediateDirectories:YESattributes:nil error:nil];
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
if (url) {
// 主要方法
[assetLibraryassetForURL:url resultBlock:^(ALAsset *asset) {
ALAssetRepresentation*rep = [asset defaultRepresentation];
Byte *buffer =(Byte*)malloc((unsigned long)rep.size);
NSUInteger buffered =[rep getBytes:buffer fromOffset:0.0length:((unsigned long)rep.size) error:nil];
NSData *data = [NSDatadataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
NSString * imagePath =[KOriginalPhotoImagePath stringByAppendingPathComponent:fileName];
[data writeToFile:imagePathatomically:YES];
} failureBlock:nil];
}
});
}
// 将原始视频的URL转化为NSData数据,写入沙盒
- (void)videoWithUrl:(NSURL *)urlwithFileName:(NSString *)fileName
{
// 解析一下,为什么视频不像图片一样一次性开辟本身大小的内存写入?
// 想想,如果1个视频有1G多,难道直接开辟1G多的空间大小来写?
ALAssetsLibrary*assetLibrary = [[ALAssetsLibrary alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
if (url) {
[assetLibraryassetForURL:url resultBlock:^(ALAsset *asset) {
ALAssetRepresentation*rep = [asset defaultRepresentation];
NSString * videoPath =[KCachesPath stringByAppendingPathComponent:fileName];
char const *cvideoPath = [videoPath UTF8String];
FILE *file =fopen(cvideoPath, "a+");
if (file) {
const int bufferSize = 1024* 1024;
// 初始化一个1M的buffer
Byte *buffer =(Byte*)malloc(bufferSize);
NSUInteger read = 0, offset = 0,written = 0;
NSError* err = nil;
if (rep.size !=0)
{
do {
read = [repgetBytes:buffer fromOffset:offset length:bufferSize error:&err];
written = fwrite(buffer,sizeof(char), read, file);
offset += read;
} while (read != 0&& !err);//没到结尾,没出错,ok继续
}
// 释放缓冲区,关闭文件
free(buffer);
buffer = NULL;
fclose(file);
file = NULL;
}
} failureBlock:nil];
}
});
}
@转载请标注:转自iOS界@迷糊小书童 谢谢