美文网首页
iOS 照片的存取

iOS 照片的存取

作者: 张三儿 | 来源:发表于2017-03-27 10:28 被阅读72次

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

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

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

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

    • 点击图片
    • 控制器传参
    • 显示在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:@"图片保存成功!"];
        }
    }
    

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

    #import "XMGSeeBigViewController.h"
    #import "XMGTopic.h"
    #import <UIImageView+WebCache.h>
    
    // #import <AssetsLibrary/AssetsLibrary.h> // iOS9开始废弃
    #import <Photos/Photos.h> // iOS9开始推荐
    
    #import <SVProgressHUD.h>
    
    @interface XMGSeeBigViewController () <UIScrollViewDelegate>
    /** 图片控件 */
    @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<PHAssetCollection *> *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 - <UIScrollViewDelegate>
    /**
     *  返回一个scrollView的子控件进行缩放
     */
    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
        return self.imageView;
    }
    
    

    <h1>2.利用UIImagePickerController取照片照片</h1>

    iOS 获取图片有三种方法:

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

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

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

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

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

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

    @interface MainViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
    

    在点击方法内模态推出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 - <UIImagePickerControllerDelegate>
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
    {
        // 销毁控制器
        [picker dismissViewControllerAnimated:YES completion:nil];
    
        // 设置图片
        self.imageView.image = info[UIImagePickerControllerOriginalImage];
    }
    

    实现代理方法

    //选择完图片后会回调 didFinishPickingMediaWithInfo 这个方法
    -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)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 照片的存取

          本文链接:https://www.haomeiwen.com/subject/ttilottx.html