美文网首页iOS接下来要研究的知识点iOS技术栈
iOS 一行代码实现调用系统相机和相册获取图片

iOS 一行代码实现调用系统相机和相册获取图片

作者: InterestingPDD | 来源:发表于2018-09-05 16:23 被阅读87次
    一行代码实现调用系统相机和相册获取图片
    5.gif
    • 使用扩展,对于简单的调用系统原生相机和相册封装了一下。只需要一行代码即可实现。
    • 可以自定义图片尺寸,传入imageSize即可,回调包括UIImage和ImageData

    1.代码.h

    #import <UIKit/UIKit.h>
    
    typedef void(^ImagePickerCompletionHandler)(NSData *imageData, UIImage *image);
    
    @interface UIViewController (ImagePicker)
    
    - (void)pickImageWithCompletionHandler:(ImagePickerCompletionHandler)completionHandler;
    - (void)pickImageWithpickImageCutImageWithImageSize:(CGSize)imageSize CompletionHandler:(ImagePickerCompletionHandler)completionHandler;
    
    @end
    
    

    2.代码.m

    //
    //  UIViewController+ImagePicker.m
    //  
    //
    //  Created by tt on 8/3/18.
    //  Copyright © 2018 . All rights reserved.
    //
    
    #import "UIViewController+ImagePicker.h"
    
    #import <objc/runtime.h>
    #import <AssetsLibrary/AssetsLibrary.h>
    #import <Photos/PHPhotoLibrary.h>
    #import <AVFoundation/AVCaptureDevice.h>
    
    
    static void *kImagePickerCompletionHandlerKey = @"kImagePickerCompletionHandlerKey";
    static void *kCameraPickerKey = @"kCameraPickerKey";
    static void *kPhotoLibraryPickerKey = @"kPhotoLibraryPickerKey";
    static void *kImageSizeKey = @"kimageSizeKey";
    static void *isCut =  @"isCut"; //截取
    
    @interface UIViewController ()<UIActionSheetDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>
    
    @property (nonatomic, strong) UIImagePickerController *cameraPicker;
    @property (nonatomic, strong) UIImagePickerController *photoLibraryPicker;
    @property (nonatomic, copy) ImagePickerCompletionHandler completionHandler;
    
    @property (nonatomic, assign) BOOL isCutImageBool;
    @property (nonatomic, assign) CGSize imageSize;
    
    @end
    
    @implementation UIViewController (ImagePicker)
    
    - (void)pickImageWithCompletionHandler:(ImagePickerCompletionHandler)completionHandler {
        self.completionHandler = completionHandler;
        [self presentChoseActionSheet];
    }
    
    
    - (void)pickImageWithpickImageCutImageWithImageSize:(CGSize)imageSize CompletionHandler:(ImagePickerCompletionHandler)completionHandler
    {
        self.completionHandler = completionHandler;
        self.isCutImageBool = YES;
        self.imageSize = imageSize;
        [self presentChoseActionSheet];
    }
    
    - (void)setUpCameraPickControllerIsEdit:(BOOL)isEdit {
        self.cameraPicker = [[UIImagePickerController alloc] init];
        self.cameraPicker.allowsEditing = isEdit; //拍照选去是否可以截取,和代理中的获取截取后的方法配合使用
        self.cameraPicker.delegate = self;
        self.cameraPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    }
    
    - (void)setUpPhotoPickControllerIsEdit:(BOOL)isEdit {
        self.photoLibraryPicker = [[UIImagePickerController alloc] init];
        self.photoLibraryPicker.allowsEditing = isEdit; // 相册选取是否截图
        self.photoLibraryPicker.delegate = self;
        //去掉毛玻璃效果 否则在ios11 下 全局设置了UIScrollViewContentInsetAdjustmentNever 导致导航栏遮住了内容视图
        self.photoLibraryPicker.navigationBar.translucent = NO;
        self.photoLibraryPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    }
    
    - (void)presentChoseActionSheet {
        
        //先创建好 不然调用的时候 第一次创建很慢 有2秒的延迟
        if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
            //判断相机可用
            [self setUpCameraPickControllerIsEdit:self.isCutImageBool];
        }
        [self setUpPhotoPickControllerIsEdit:self.isCutImageBool];
        
        UIAlertController * actionController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
        UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            
        }];
        
        UIAlertAction * takePhotoAction = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                if (granted) {
                    [self presentViewController:self.cameraPicker animated:YES completion:nil];
                }
                else {
                    UIAlertController * noticeAlertController = [UIAlertController alertControllerWithTitle:@"未开启相机权限,请到设置界面开启" message:nil preferredStyle:UIAlertControllerStyleAlert];
                    UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                        
                    }];
                    
                    UIAlertAction * okAction = [UIAlertAction actionWithTitle:@"现在就去" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                        //跳转到设置界面
                        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:^(BOOL success) {
                            
                        }];
                    }];
                    
                    [noticeAlertController addAction:cancelAction];
                    [noticeAlertController addAction:okAction];
                    [self presentViewController:noticeAlertController animated:YES completion:^{
                        
                    }];
                }
            }];
    
        }];
        
        UIAlertAction * choseFromAlbumAction = [UIAlertAction actionWithTitle:@"从相册选取" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            //判断相册权限
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                if (status == PHAuthorizationStatusNotDetermined || status == PHAuthorizationStatusAuthorized) {
                    //未知的   第一次访问
    
                    [self presentViewController:self.photoLibraryPicker animated:YES completion:nil];
    
                }
                else {
                    UIAlertController * noticeAlertController = [UIAlertController alertControllerWithTitle:@"未开启相册权限,请到设置界面开启" message:nil preferredStyle:UIAlertControllerStyleAlert];
                    UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                        
                    }];
                    
                    UIAlertAction * okAction = [UIAlertAction actionWithTitle:@"现在就去" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                        //跳转到设置界面
                        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:^(BOOL success) {
                            
                        }];
                    }];
                    
                    [noticeAlertController addAction:cancelAction];
                    [noticeAlertController addAction:okAction];
                    [self presentViewController:noticeAlertController animated:YES completion:^{
                        
                    }];
                }
            }];
    
        }];
        
        [actionController addAction:cancelAction];
        [actionController addAction:takePhotoAction];
        [actionController addAction:choseFromAlbumAction];
        
        [self presentViewController:actionController animated:YES completion:^{
            
        }];
    }
    
    #pragma mark <UIImagePickerControllerDelegate>
    
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
        [picker dismissViewControllerAnimated:YES completion:nil];
        UIImage *editedimage = [[UIImage alloc] init];
        if(self.isCutImageBool){
             //获取裁剪的图
            editedimage = info[@"UIImagePickerControllerEditedImage"]; //获取裁剪的图
            CGSize imageSize = CGSizeMake(413, 626);
            if (self.imageSize.height>0) {
                imageSize = self.imageSize;
            }
            editedimage = [self reSizeImage:editedimage toSize:imageSize];
        }
        else{
            editedimage = info[@"UIImagePickerControllerOriginalImage"];
        }
        NSData *imageData = UIImageJPEGRepresentation(editedimage, 0.0001);//首次进行压缩
        UIImage *image = [UIImage imageWithData:imageData];
        //图片限制大小不超过 1M     CGFloat  kb =   data.lenth / 1000;  计算kb方法 os 按照千进制计算
        while (imageData.length/1000 > 1024) {
            NSLog(@"图片超过1M 压缩");
            imageData = UIImageJPEGRepresentation(image, 0.5);
            image = [UIImage imageWithData:imageData];
        }
        self.completionHandler(imageData, image);
    }
    
    - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
        [picker dismissViewControllerAnimated:YES completion:nil];
    }
    
    - (UIImage *)reSizeImage:(UIImage *)image toSize:(CGSize)reSize
    {
        UIGraphicsBeginImageContext(CGSizeMake(reSize.width, reSize.height));
        [image drawInRect:CGRectMake(0, 0, reSize.width, reSize.height)];
        UIImage *reSizeImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        return reSizeImage;
    }
    
    #pragma mark - setters & getters
    
    - (void)setCompletionHandler:(ImagePickerCompletionHandler)completionHandler {
        objc_setAssociatedObject(self, kImagePickerCompletionHandlerKey, completionHandler, OBJC_ASSOCIATION_COPY);
    }
    
    - (ImagePickerCompletionHandler)completionHandler {
        return objc_getAssociatedObject(self, kImagePickerCompletionHandlerKey);
    }
    
    - (void)setCameraPicker:(UIImagePickerController *)cameraPicker {
        objc_setAssociatedObject(self, kCameraPickerKey, cameraPicker, OBJC_ASSOCIATION_RETAIN);
    }
    
    - (UIImagePickerController *)cameraPicker {
        return objc_getAssociatedObject(self, kCameraPickerKey);;
    }
    
    - (void)setPhotoLibraryPicker:(UIImagePickerController *)photoLibraryPicker {
        objc_setAssociatedObject(self, kPhotoLibraryPickerKey, photoLibraryPicker, OBJC_ASSOCIATION_RETAIN);
    }
    
    - (UIImagePickerController *)photoLibraryPicker {
        return objc_getAssociatedObject(self, kPhotoLibraryPickerKey);
    }
    
    - (void)setIsCutImageBool:(BOOL)isCutImageBool {
        return objc_setAssociatedObject(self, isCut, @(isCutImageBool), OBJC_ASSOCIATION_RETAIN);
    }
    
    - (BOOL)isCutImageBool {
        return [objc_getAssociatedObject(self, isCut) boolValue];
    }
    
    - (void)setImageSize:(CGSize)imageSize {
        return objc_setAssociatedObject(self, kImageSizeKey, [NSValue valueWithCGSize:imageSize], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (CGSize)imageSize {
        NSValue * value = objc_getAssociatedObject(self, kImageSizeKey);
        return  value.CGSizeValue;
    }
    
    @end
    
    
    
    1. 然后就只需要一句代码调用就行啦,在控制器里导入头文件
    #import "UIViewController+ImagePicker.h"
    

    2 .一句代码调用

    不使用裁剪功能,获取原图
        [self pickImageWithCompletionHandler:^(NSData *imageData, UIImage *image) {
            //这里就拿到图片了
    
        }];
    
    使用裁剪功能-自定义图片大小 我设置为400*400
        [self pickImageWithpickImageCutImageWithImageSize:CGSizeMake(400, 400) CompletionHandler:^(NSData *imageData, UIImage *image) {
           //这里就拿到图片了
        }];
    

    • 包括了相册和相机权限判断,提示用户开启访问权限并跳转到设置界面开启。
    • 需要iOS8以上,因为使用了UIAlertController。
    • info.plist文件添加相机和相册访问权限key 和value 文字描述随便你写什么都行,个人喜欢怎么写就怎么写。🙃
      1 .相机
      <key>Privacy - Camera Usage Description</key>
      <string>是否允许App访问相机</string>
      2.相册
      <key>Privacy - Photo Library Usage Description</key>
      <string>是否允许App访问相册</string>
    • 🍉ps:因为系统的界面按钮文字是英文的,比如相机界面的 取消 按钮,和相册界面的 取消 按钮,想要变成中文的话。
      info.plist文件里找到
      <key>Localization native development region</key>
      值改为
      <string>China</string>
      然后那些按钮的文字就变成中文了。

    相关文章

      网友评论

        本文标题:iOS 一行代码实现调用系统相机和相册获取图片

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