iOS 照片的存取

保存照片是一件极其恶心的事!下面介绍一下照片的存和取

iOS 10推出了访问权限,在plist里添加即可

 
NSPhotoLibraryUsageDescription 
App需要您的同意,才能访问相册 
 
NSCameraUsageDescription 
App需要您的同意,才能访问相机 
 
NSMicrophoneUsageDescription 
App需要您的同意,才能访问麦克风 
 
NSLocationUsageDescription 
App需要您的同意,才能访问位置 
 
NSLocationWhenInUseUsageDescription 
App需要您的同意,才能在使用期间访问位置 
 
NSLocationAlwaysUsageDescription 
App需要您的同意,才能始终访问位置 
 
NSCalendarsUsageDescription 
App需要您的同意,才能访问日历 
 
NSRemindersUsageDescription 
App需要您的同意,才能访问提醒事项 
 
NSMotionUsageDescription App需要您的同意,才能访问运动与健身 
 
NSHealthUpdateUsageDescription 
App需要您的同意,才能访问健康更新  
 
NSHealthShareUsageDescription 
App需要您的同意,才能访问健康分享 
 
NSBluetoothPeripheralUsageDescription 
App需要您的同意,才能访问蓝牙 
 
NSAppleMusicUsageDescription 
App需要您的同意,才能访问媒体资料库

1.照片的存储(这里会用两个方法实现,一种是与其他照片一样存在set里,另一种是新创建一个set存储)

iOS 照片的存取_第1张图片
iOS 照片的存取_第2张图片
  • 点击图片
  • 控制器传参
  • 显示在ScrollView上, 并设置好图片的宽高

方法一

self.imageView.userInteractionEnabled = YES;
    [self.imageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(seeBig)]];
ZJSeeBigViewController *seeBig = [[ZJSeeBigViewController alloc] init];
    seeBig.topic = self.topic;
    [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:seeBig animated:YES completion:nil];
// scrollView
    UIScrollView *scrollView = [[UIScrollView alloc] init];
    scrollView.delegate = self;
    scrollView.frame = [UIScreen mainScreen].bounds;
    [self.view insertSubview:scrollView atIndex:0];
    
    // scrollView.backgroundColor = [UIColor redColor];
    // scrollView.frame = self.view.bounds;
    // scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    
    // imageView
    UIImageView *imageView = [[UIImageView alloc] init];
    [imageView sd_setImageWithURL:[NSURL URLWithString:self.topic.large_image] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
        if (image == nil) return; // 图片下载失败
        self.saveButton.enabled = YES;
    }];
    [scrollView addSubview:imageView];
    
    imageView.xmg_width = scrollView.xmg_width;
    imageView.xmg_height = self.topic.height * imageView.xmg_width / self.topic.width;
    imageView.xmg_x = 0;
    
    if (imageView.xmg_height >= scrollView.xmg_height) { // 图片高度超过整个屏幕
        imageView.xmg_y = 0;
        // 滚动范围
        scrollView.contentSize = CGSizeMake(0, imageView.xmg_height);
    } else { // 居中显示
        imageView.xmg_centerY = scrollView.xmg_height * 0.5;
    }
    self.imageView = imageView;

    // 缩放比例
    CGFloat scale =  self.topic.width / imageView.xmg_width;
    if (scale > 1.0) {
        scrollView.maximumZoomScale = scale;
    }
- (IBAction)save {

    UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (error) {
        [SVProgressHUD showErrorWithStatus:@"图片保存失败!"];
    } else {
        [SVProgressHUD showSuccessWithStatus:@"图片保存成功!"];
    }
}

方法二(这里涉及到一个新的类库 在保存照片的时候,我们需要先判断手机里是否有改软件已经存储的collectionSet 如果有直接往里存,没有要创建,保存之前会涉及到一个用户quan)

#import "XMGSeeBigViewController.h"
#import "XMGTopic.h"
#import 

// #import  // iOS9开始废弃
#import  // iOS9开始推荐

#import 

@interface XMGSeeBigViewController () 
/** 图片控件 */
@property (nonatomic, weak) UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UIButton *saveButton;
@end

@implementation XMGSeeBigViewController

static NSString * XMGAssetCollectionTitle = @"5期-百思不得姐";

//点击保存按钮
- (IBAction)save {
    /*
     PHAuthorizationStatusNotDetermined,     用户还没有做出选择
     PHAuthorizationStatusDenied,            用户拒绝当前应用访问相册(用户当初点击了"不允许")
     PHAuthorizationStatusAuthorized         用户允许当前应用访问相册(用户当初点击了"好")
     PHAuthorizationStatusRestricted,        因为家长控制, 导致应用无法方法相册(跟用户的选择没有关系)
     */
    
    // 判断授权状态
    PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
    if (status == PHAuthorizationStatusRestricted) { // 因为家长控制, 导致应用无法方法相册(跟用户的选择没有关系)
        [SVProgressHUD showErrorWithStatus:@"因为系统原因, 无法访问相册"];
    } else if (status == PHAuthorizationStatusDenied) { // 用户拒绝当前应用访问相册(用户当初点击了"不允许")
        XMGLog(@"提醒用户去[设置-隐私-照片-xxx]打开访问开关");
    } else if (status == PHAuthorizationStatusAuthorized) { // 用户允许当前应用访问相册(用户当初点击了"好")
        [self saveImage];
    } else if (status == PHAuthorizationStatusNotDetermined) { // 用户还没有做出选择
        // 弹框请求用户授权
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
            if (status == PHAuthorizationStatusAuthorized) { // 用户点击了好
                [self saveImage];
            }
        }];
    }
}

- (void)saveImage
{
    // PHAsset : 一个资源, 比如一张图片\一段视频
    // PHAssetCollection : 一个相簿
    
    // PHAsset的标识, 利用这个标识可以找到对应的PHAsset对象(图片对象)
    __block NSString *assetLocalIdentifier = nil;
    
    // 如果想对"相册"进行修改(增删改), 那么修改代码必须放在[PHPhotoLibrary sharedPhotoLibrary]的performChanges方法的block中
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        // 1.保存图片A到"相机胶卷"中
        // 创建图片的请求
        assetLocalIdentifier = [PHAssetCreationRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset.localIdentifier;
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
        if (success == NO) {
            [self showError:@"保存图片失败!"];
            return;
        }
        
        // 2.获得相簿
        PHAssetCollection *createdAssetCollection = [self createdAssetCollection];
        if (createdAssetCollection == nil) {
            [self showError:@"创建相簿失败!"];
            return;
        }
        
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            // 3.添加"相机胶卷"中的图片A到"相簿"D中
            
            // 获得图片
            PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetLocalIdentifier] options:nil].lastObject;
            
            // 添加图片到相簿中的请求
            PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdAssetCollection];
            
            // 添加图片到相簿
            [request addAssets:@[asset]];
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            if (success == NO) {
                [self showError:@"保存图片失败!"];;
            } else {
                [self showSuccess:@"保存图片成功!"];;
            }
        }];
    }];
}

/**
 *  获得相簿
 */
- (PHAssetCollection *)createdAssetCollection
{
    // 从已存在相簿中查找这个应用对应的相簿
    PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    for (PHAssetCollection *assetCollection in assetCollections) {
        if ([assetCollection.localizedTitle isEqualToString:XMGAssetCollectionTitle]) {
            return assetCollection;
        }
    }
    
    // 没有找到对应的相簿, 得创建新的相簿
    
    // 错误信息
    NSError *error = nil;
    
    // PHAssetCollection的标识, 利用这个标识可以找到对应的PHAssetCollection对象(相簿对象)
    __block NSString *assetCollectionLocalIdentifier = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
        // 创建相簿的请求
        assetCollectionLocalIdentifier = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:XMGAssetCollectionTitle].placeholderForCreatedAssetCollection.localIdentifier;
    } error:&error];
    
    // 如果有错误信息
    if (error) return nil;
    
    // 获得刚才创建的相簿
    return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[assetCollectionLocalIdentifier] options:nil].lastObject;
}

- (void)showSuccess:(NSString *)text
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [SVProgressHUD showSuccessWithStatus:text];
    });
}

- (void)showError:(NSString *)text
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [SVProgressHUD showErrorWithStatus:text];
    });
}

#pragma mark - 
/**
 *  返回一个scrollView的子控件进行缩放
 */
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.imageView;
}

2.利用UIImagePickerController取照片照片

iOS 获取图片有三种方法:

 1. 直接调用摄像头拍照
 2. 从相册中选择
 3. 从图库中选择

UIImagePickerController 类来获取图片视频,大体分为以下几个步骤:

 1. 初始化UIImagePickerController 类;
 2. 设置UIImagePickerController 实例的数据来源类型(下面解释);
 3. 设置设置代理;
 4. 如果需要做图片修改的话设置allowsEditing =yes。

数据来源类型一共有三种:

enum {
     UIImagePickerControllerSourceTypePhotoLibrary ,//来自图库
     UIImagePickerControllerSourceTypeCamera ,//来自相机
     UIImagePickerControllerSourceTypeSavedPhotosAlbum //来自相册
     };

获取图片首先签订两个协议

@interface MainViewController ()

在点击方法内模态推出UIImagePickerController
从相册选取(需给用户选择哪种方式获取图片)

/**
 *  利用UIImagePickerController挑选图片
 */
- (void)getImageFromIpc
{
    // UIImagePickerController : 可以从系统自带的App(照片\相机)中获得图片

    // 判断相册是否可以打开
    if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;

    UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
    // 打开照片应用(显示所有相簿)
    ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    // 打开照片应用(只显示"时刻"这个相簿)
    // ipc.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    // 照相机
    // ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
    ipc.delegate = self;
    [self presentViewController:ipc animated:YES completion:nil];
}

#pragma mark - 
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    // 销毁控制器
    [picker dismissViewControllerAnimated:YES completion:nil];

    // 设置图片
    self.imageView.image = info[UIImagePickerControllerOriginalImage];
}

实现代理方法

//选择完图片后会回调 didFinishPickingMediaWithInfo 这个方法
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(@"info = %@",info);
//隐藏控制器
  [picker dismissViewControllerAnimated:YES completion:nil];
//给imageView 赋值图片
  imageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
}
//导航条上面的 Cancel 的点击方法
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
//隐藏控制器
  [picker dismissViewControllerAnimated:YES completion:nil];
}

你可能感兴趣的:(iOS 照片的存取)