相机与相册

调用系统相机和相册

添加权限描述:

或者直接在Info.plist中添加配置:

<key>NSPhotoLibraryAddUsageDescription</key>
<string>保存拍照需要该权限</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>测试图库需要权限</string>
<key>NSCameraUsageDescription</key>
<string>测试相机需要权限</string>

图库动态权限请求:

  • PHAuthorizationStatusNotDetermined:用户从未进行过授权等处理,首次访问相应内容会提示用户进行授权
  • PHAuthorizationStatusRestricted:应用无权访问,且当前用户无法改变这个权限,比如:家长控制
  • PHAuthorizationStatusDenied:用户拒绝访问
  • PHAuthorizationStatusAuthorized:用户已授权,允许访问
  • PHAuthorizationStatusLimited: 用户已授权此应用程序进行有限照片库访问(iOS14新增)

完整示例:

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <Photos/Photos.h>

@interface ViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate>{
    UIImagePickerController *_picker;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info{
    [picker dismissViewControllerAnimated:YES completion:nil];
    UIImage *image = info[UIImagePickerControllerEditedImage];
    //    UIImage *image = info[UIImagePickerControllerOriginalImage];
    NSLog(@"%@",info);

  if ([picker sourceType] == UIImagePickerControllerSourceTypeCamera) {
    UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
  } 
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
    NSLog(@"image = %@, error = %@, contextInfo = %@", image, error, contextInfo);
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    [picker dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)onclick:(UIButton *)sender {
    switch (sender.tag) {
        case 1: // 打开相机
            [self openCamera];
            break;
        case 2: // 打开图库
            [self openPhotoLib];
            break;
        default:
            break;
    }
}

- (UIImagePickerController*)getPicker{
    if(_picker == nil){
        _picker = [[UIImagePickerController alloc]init];
        _picker.delegate = self;
        _picker.allowsEditing = YES;
    }
    return  _picker;
}

-(void)openPhotoLib{
    PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
    if(status == PHAuthorizationStatusNotDetermined){
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status){
            NSLog(@"current thread is %@",[NSThread currentThread]);
            dispatch_async(dispatch_get_main_queue(), ^{
                if(status == PHAuthorizationStatusAuthorized){
                    [self openImagePicker];
                }
            });
        }];
    }else if (status == PHAuthorizationStatusDenied || status == PHAuthorizationStatusRestricted){
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"未获授权,请转到设置页面授权!" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel  handler:^(UIAlertAction * action){
            [self dismissViewControllerAnimated:YES completion:nil];
        }];
        UIAlertAction *setting = [UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault  handler:^(UIAlertAction * action){
            NSURL *url = [NSURL URLWithString: UIApplicationOpenSettingsURLString];
            if([[UIApplication sharedApplication] canOpenURL:url]){
                [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
            }
        }];
        [alert addAction:cancel];
        [alert addAction:setting];
        [self presentViewController:alert animated:YES completion:nil];
    }else{
        [self openImagePicker];
    }
}

-(void)openImagePicker{
    UIImagePickerController *picker = [self getPicker];
    // 类型为图库
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    [self presentViewController:picker animated:YES completion:nil];
}

-(void)openCamera{
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if(status == AVAuthorizationStatusNotDetermined){
        // 首次请求用户授权
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted){
            dispatch_async(dispatch_get_main_queue(), ^{
                if(granted){
                    [self startCamera];
                }else{
                    NSLog(@"=========== 拒绝授权 ==========");
                }
            });
        }];
    }else if (status == AVAuthorizationStatusDenied){
        NSLog(@"=========== 未获得授权 ==========");
    }else{
        NSLog(@"=========== 已经授权 ==========");
        [self startCamera];
    }
}

-(void)startCamera{
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
        UIImagePickerController *picker = [self getPicker];
          // 类型为相机
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        // 使用后置摄像头
        picker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
        // 设置为拍照模式
        picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
        [self presentViewController:picker animated:YES completion:nil];
    }
}
@end

保存照片的处理:

  • UIImageWriteToSavedPhotosAlbum:需要实现(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo方法

  • creationRequestForAssetFromImage

    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        [PHAssetChangeRequest creationRequestForAssetFromImage:image];
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
        NSLog(@"success = %d, error = %@", success, error);
    }];
    

以上两种方式保存照片,都会进行一定程度的压缩,可使用如下方式保存原始照片:

UIImage * imgsave = image;
// 将图片存储到本地沙盒中
NSString * path = [NSHomeDirectory() stringByAppendingString:@"/Documents/test.jpg"];
[UIImagePNGRepresentation(imgsave) writeToFile:path atomically:YES];

// 获取URL,根据URL将图片转存至图库
NSURL *imagePathUrl = [NSURL fileURLWithPath:path];

// 这里要先判断是否获取图库的权限,然后调用以下代码转存到图库
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:imagePathUrl];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
    if (success) NSLog(@"保存成功");
    else NSLog(@"保存失败");
}];

注意,启动的照片选择页面可能是英文的,如需显示为中文,则需要在Info.plist中配置一下,将值修改为china


公众号“编程之路从0到1”

20190301102949549

Copyright © Arcticfox 2021 all right reserved,powered by Gitbook文档修订于: 2022-05-01 12:20:20

results matching ""

    No results matching ""