码迷,mamicode.com
首页 > 移动开发 > 详细

iOS-获取本地相册的所有图片展示在cell上

时间:2016-06-29 19:05:01      阅读:706      评论:0      收藏:0      [点我收藏+]

标签:

 

本文Demo GitHub地址:https://github.com/xue-ios/Share_First  欢迎大家的Followers和Stars

声明:本文为本人原创作品~转载请注明出处~谢谢配合!

准备工作

1.下载MJExtension 数据转模型库

2.自定义cell 大致布局如下

大致实现的效果如下 《我适配横屏了 大家可随意》

让TableView支持横屏的代码如下:

 //支持横屏

  myTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;

技术分享

 

基础知识

现在iOS9之后用#import <Photos/Photos.h>这个框架 据说更为强大 稍后有时间我会研究研究一下贴出来给大家看一下

首先用到了这几个框架 这是iOS9以下的框架和类

#import <AssetsLibrary/ALAsset.h>

#import <AssetsLibrary/ALAssetsLibrary.h>

#import <AssetsLibrary/ALAssetsGroup.h>

#import <AssetsLibrary/ALAssetRepresentation.h>

重要方法

// 将原始图片的URL转化为NSData数据,写入沙盒

- (void)imageWithUrl:(NSURL *)url withFileName:(NSString *)fileName

{

    // 进这个方法的时候也应该加判断,如果已经转化了的就不要调用这个方法了

    // 如何判断已经转化了,通过是否存在文件路径

    ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];

    // 创建存放原始图的文件夹--->OriginalPhotoImages

    NSFileManager * fileManager = [NSFileManager defaultManager];

    if (![fileManager fileExistsAtPath:KOriginalPhotoImagePath]) {

        [fileManager createDirectoryAtPath:KOriginalPhotoImagePath withIntermediateDirectories:YES attributes:nil error:nil];

    }

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        if (url) {

            // 主要方法

            [assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {

                ALAssetRepresentation *rep = [asset defaultRepresentation];

                Byte *buffer = (Byte*)malloc((unsigned long)rep.size);

                NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:((unsigned long)rep.size) error:nil];

                NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];

                NSString * imagePath = [KOriginalPhotoImagePath stringByAppendingPathComponent:fileName];

                [data writeToFile:imagePath atomically:YES];

                

                

            } failureBlock:nil];

        }

    });

}

// 将原始视频的URL转化为NSData数据,写入沙盒

- (void)videoWithUrl:(NSURL *)url withFileName:(NSString *)fileName

{

    // 解析一下,为什么视频不像图片一样一次性开辟本身大小的内存写入?

    // 想想,如果1个视频有1G,难道直接开辟1G多的空间大小来写?

    ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        if (url) {

            [assetLibrary assetForURL: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;

                    // 初始化一个1Mbuffer

                    Byte *buffer = (Byte*)malloc(bufferSize);

                    NSUInteger read = 0, offset = 0, written = 0;

                    NSError* err = nil;

                    if (rep.size != 0)

                    {

                        do {

                            read = [rep getBytes: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];

        }

    });

}

我们的照片存在本地相册取得时候得出来的是ALAssetsGroup这个类里面的数据 需要我们把图片写入沙河Cache目录中

然后再进行操作 代码全部在我的Git中 想学习的可以下载下来看一下 

以下是我VC里面的所有代码 注释的很清楚 大家可以看一下 另外本文此Demo我已上传至Git 欢迎大家的

#import "ViewController.h"
#import <Social/Social.h>
#import <AssetsLibrary/ALAsset.h>
#import <AssetsLibrary/ALAssetsLibrary.h>
#import <AssetsLibrary/ALAssetsGroup.h>
#import <AssetsLibrary/ALAssetRepresentation.h>
#import "YY_FileTableViewCell.h"
#import "MJExtension.h"
#import "Model.h"
#import <CoreLocation/CoreLocation.h>
// 照片原图路径
#define KOriginalPhotoImagePath   [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"OriginalPhotoImages"]

// 视频URL路径
#define KVideoUrlPath   [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"VideoURL"]

// caches路径
#define KCachesPath   [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]

@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
{
    UITableView  *myTableView;
    NSMutableArray *imagesList;
    NSMutableArray *timeStringList;
    NSMutableArray *locationStringList;
    NSMutableArray *locationLists;
    NSMutableArray *models;
    NSMutableArray *locationsModels;
    CLGeocoder *geocoder;
}

 @end

@implementation ViewController

- (void)viewWillAppear:(BOOL)animated{
    
    [super viewWillAppear:animated];
    
    [self getAllPhotosFromSystemPhotosLibrary];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    self.edgesForExtendedLayout = UIRectEdgeNone;
    
    self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
    
}
- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    imagesList = [NSMutableArray array];
    
    timeStringList = [NSMutableArray array];
    
    locationStringList = [NSMutableArray array];
    
    models = [NSMutableArray array];
    
    locationsModels = [NSMutableArray array];
    
    locationLists = [NSMutableArray array];
    
    geocoder = [[CLGeocoder alloc]init];
    
    [self loadUI];
}

- (void)loadUI{
    
    myTableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStylePlain];
    myTableView.delegate = self;
    myTableView.rowHeight = 100;
    myTableView.dataSource = self;
    //支持横屏
    myTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
    
    [self.view addSubview:myTableView];
    /*
     34.3830750000 Latitude
     114.2750620000 Longitude
     */
    //测试
}

#pragma mark ======获取到系统相册的所有图片=======
- (NSString *)stringFromDate:(NSDate *)date{
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    
    //zzz表示时区,zzz可以删除,这样返回的日期字符将不包含时区信息。
    
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    
    
    NSString *destDateString = [dateFormatter stringFromDate:date];
    
    
    return destDateString;
    
}

- (NSString *)returnPlaceStringLatitudeText:(NSString *)LatitudeText LongtitudeText:(NSString *)LongtitudeText{
    
    //dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    CLLocation *location = [[CLLocation alloc]initWithLatitude:[LatitudeText doubleValue] longitude:[LongtitudeText doubleValue]];
    
    __block NSString *place;
    
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        
        if (error||placemarks.count==0) {
            
            place = @"未知的位置";
            
            NSLog(@"%@",place);
            
        }
        else{
            
            place = placemarks.firstObject.name;
            
            NSLog(@"%@",place);
        }
        
    }];

    return place;
}

//获取相册里的所有图片
- (void)getAllPhotosFromSystemPhotosLibrary{
    /*
    
    NSString *paths = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"OriginalPhotoImages"];
    
    NSLog(@"paths%@",paths);
    
    如果本地存储的路径里有 则读取本地的目录的 如果没有则读取相册里的
    
    if (paths) {
        
        NSFileManager *fm = [NSFileManager defaultManager];
        
        //获取目录下图片的所有名字 比如说IMG_0004.JPG
        NSArray *files = [fm subpathsAtPath:paths];
        
        for (NSString *fileName in files) {
            
            NSLog(@"%@",fileName);
            
            NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"OriginalPhotoImages/%@",fileName]];
            
            UIImage *image = [UIImage imageWithContentsOfFile:path];
            
            NSLog(@"image = %@",image);
            
            [imagesList addObject:image];
        }
    
    }
    */
    ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc]init];//生成整个photolibrary的实例
    
    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {//获取所有group
        [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
            //从group里面
            NSString* assetType = [result valueForProperty:ALAssetPropertyType];
            
            if ([assetType isEqualToString:ALAssetTypePhoto]) {
                //NSLog(@"Photo");
                NSDate *date= [result valueForProperty:ALAssetPropertyDate];
                UIImage *image = [UIImage imageWithCGImage:[result thumbnail]];
                NSString *fileName = [[result defaultRepresentation] filename];
                NSURL *url = [[result defaultRepresentation] url];
                NSDictionary *dict = [[result defaultRepresentation]metadata];
                
                //int64_t fileSize = [[result defaultRepresentation] size];
                /*
                 2016-06-27 13:55:17.024 Share_First[2941:1062832] Photo
                 2016-06-27 13:55:17.029 Share_First[2941:1062832] date = 2011-03-13 00:17:25 +0000
                 2016-06-27 13:55:17.030 Share_First[2941:1062832] fileName = IMG_0001.JPG
                 2016-06-27 13:55:17.030 Share_First[2941:1062832] url = assets-library://asset/asset.JPG?id=106E99A1-4F6A-45A2-B320-B0AD4A8E8473&ext=JPG
                 2016-06-27 13:55:17.030 Share_First[2941:1062832] fileSize = 1896240
                 */
                //NSLog(@"元数据=%@",dict);
                //NSLog(@"date = %@",date);//照片拍摄时间
                //NSLog(@"fileName = %@",fileName);//照片名称
                //NSLog(@"url = %@",url);//照片文件URL(非网络URL 浏览器上输入这个URL找不到这张图片 我试了)
                //NSLog(@"fileSize = %lld",fileSize);//照片文件size 具体单位不知道是什么 肯定不是MshareImageView
                
                //latitude:纬度
                //longitude:经度
                
                NSString *Longitude = dict[@"{GPS}"][@"Longitude"];
                NSString *Latitude  = dict[@"{GPS}"][@"Latitude"];
                
                if (Longitude==nil||Latitude==nil) {
                    Longitude = @"";
                    Latitude  = @"";
                }
                
                NSLog(@"longitude= %@ Latitude = %@",Longitude,Latitude);
                
                [locationLists addObject:@{@"Longitude":Longitude,@"Latitude":Latitude}];
                
                locationsModels = [Model mj_objectArrayWithKeyValuesArray:locationLists];
                
                [timeStringList addObject:@{@"timeString":[self stringFromDate:date]}];
                
                models = [Model mj_objectArrayWithKeyValuesArray:timeStringList];
                
                [imagesList addObject:image];
  
                //读取完照片之后写入APP沙河cache目录  这个方法我在网上找到的
                
                [self imageWithUrl:url withFileName:fileName];
                
                //回到主线程更新UI
                dispatch_async(dispatch_get_main_queue(), ^{
                    
                    [myTableView reloadData];
                });
             }else if([assetType isEqualToString:ALAssetTypeVideo]){
                
                NSLog(@"Video");
                
                NSDate *date= [result valueForProperty:ALAssetPropertyDate];
                UIImage *image = [UIImage imageWithCGImage:[result thumbnail]];
                NSString *fileName = [[result defaultRepresentation] filename];
                NSURL *url = [[result defaultRepresentation] url];
                int64_t fileSize = [[result defaultRepresentation] size];
                NSLog(@"date = %@",date);
                NSLog(@"fileName = %@",fileName);
                NSLog(@"url = %@",url);
                NSLog(@"fileSize = %lld",fileSize);
                NSLog(@"image = %@",image);
                
                [self videoWithUrl:url withFileName:fileName];
                
            }else if([assetType isEqualToString:ALAssetTypeUnknown]){
                NSLog(@"Unknow AssetType");
            }
            //-----------可解开----------
            /*
            NSDictionary *assetUrls = [result valueForProperty:ALAssetPropertyURLs];
            
            for (NSString *assetURLKey in assetUrls) {
                
                NSLog(@"%@",[assetUrls objectForKey:assetURLKey]);
                
            }
            */
        }];
    } failureBlock:^(NSError *error) {
        NSLog(@"Enumerate the asset groups failed.");
    }];
        
    
}
// 将原始图片的URL转化为NSData数据,写入沙盒
- (void)imageWithUrl:(NSURL *)url withFileName:(NSString *)fileName
{
    // 进这个方法的时候也应该加判断,如果已经转化了的就不要调用这个方法了
    // 如何判断已经转化了,通过是否存在文件路径
    ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
    // 创建存放原始图的文件夹--->OriginalPhotoImages
    NSFileManager * fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:KOriginalPhotoImagePath]) {
        [fileManager createDirectoryAtPath:KOriginalPhotoImagePath withIntermediateDirectories:YES attributes:nil error:nil];
    }
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        if (url) {
            // 主要方法
            [assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {
                ALAssetRepresentation *rep = [asset defaultRepresentation];
                Byte *buffer = (Byte*)malloc((unsigned long)rep.size);
                NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:((unsigned long)rep.size) error:nil];
                NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
                NSString * imagePath = [KOriginalPhotoImagePath stringByAppendingPathComponent:fileName];
                [data writeToFile:imagePath atomically:YES];
                
                
            } failureBlock:nil];
        }
    });
}
// 将原始视频的URL转化为NSData数据,写入沙盒
- (void)videoWithUrl:(NSURL *)url withFileName:(NSString *)fileName
{
    // 解析一下,为什么视频不像图片一样一次性开辟本身大小的内存写入?
    // 想想,如果1个视频有1G多,难道直接开辟1G多的空间大小来写?
    ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        if (url) {
            [assetLibrary assetForURL: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 = [rep getBytes: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];
        }
    });
}

/*
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 {
       // 1.判断平台是否可用
        if (![SLComposeViewController isAvailableForServiceType:SLServiceTypeSinaWeibo]) {
                 NSLog(@"平台不可用,或者没有配置相关的帐号");
                 return;
             }
    
         // 2.创建分享的控制器
         SLComposeViewController *composeVc = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeSinaWeibo];
    
        // 2.1.添加分享的文字
           [composeVc setInitialText:@"我是一个codeMan"];
    
         // 2.2.添加一个图片
         [composeVc addImage:[UIImage imageNamed:@"xingxing"]];
    
         // 2.3.添加一个分享的链接
         [composeVc addURL:[NSURL URLWithString:@"www.baidu.com"]];
    
         // 3.弹出分享控制器
         [self presentViewController:composeVc animated:YES completion:nil];
    
         // 4.监听用户点击了取消还是发送
         composeVc.completionHandler = ^(SLComposeViewControllerResult result) {
                 if (result == SLComposeViewControllerResultCancelled) {
                         NSLog(@"点击了取消");
                     } else {
                             NSLog(@"点击了发送");
                         }
             };
 
 }
*/
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    
    return  models.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    YY_FileTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[YY_FileTableViewCell ID]];;
    if (!cell) {
        cell = [YY_FileTableViewCell YY_FileTableViewCell];
    }
    cell.block = ^(YY_FileTableViewCell *cell){
        //点击按钮的时候调用
        NSIndexPath *path = [tableView indexPathForCell:cell];
        NSLog(@"组%ld 行%ld ",path.section,path.row);
    };
    Model *model = models[indexPath.row];
    Model *model1 = locationsModels[indexPath.row];
    
    NSLog(@"Latitude = %@",model1.Latitude);
    NSLog(@"Longitude = %@",model1.Longitude);
    
    cell.Longtitude = model1.Longitude;
    cell.Latitude   = model1.Latitude;
    
    cell.timeLabel.adjustsFontSizeToFitWidth = YES;
    cell.locationLabel.adjustsFontSizeToFitWidth = YES;
    
    cell.timeLabel.text = model.timeString;
    
    cell.shareImageView.image = imagesList[indexPath.row];
    
    cell.locationLabel.text = [NSString stringWithFormat:@"纬度 = %@ 经度 = %@",model1.Latitude,model1.Longitude];
    
    return cell;
}
- (void)didReceiveMemoryWarning {
    
    [super didReceiveMemoryWarning];
    
    // Dispose of any resources that can be recreated.
}

@end

  

代码方法没有太多的封装~写的有点乱 大家见谅 另外大家如有对本文有更好的建议和理解记得comment我一下~我们相互学习!

 

iOS-获取本地相册的所有图片展示在cell上

标签:

原文地址:http://www.cnblogs.com/start-ios/p/5627708.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!