iOS开发—— UIImagePickerController获取相册和拍照

  一、简单的拍照显示,或是从相册中直接选取照片

#import "ViewController.h"

@interface ViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate>{

    UIImageView *imageView;

}

@end

@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 80, self.view.bounds.size.width-40, 300)];

    imageView.backgroundColor = [UIColor grayColor];

    [self.view addSubview:imageView];

    UIButton *button = [UIButton buttonWithType:(UIButtonTypeCustom)];

    button.frame = CGRectMake(100, 400, 100, 50);

    button.backgroundColor = [UIColor redColor];

    [button setTitle:@"相机" forState:UIControlStateNormal];

    [button addTarget:self action:@selector(camera) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:button];

    

    UIButton *mButton = [UIButton buttonWithType:(UIButtonTypeCustom)];

    mButton.frame = CGRectMake(100, 470, 100, 50);

    mButton.backgroundColor = [UIColor redColor];

    [mButton setTitle:@"相册" forState:UIControlStateNormal];

    [mButton addTarget:self action:@selector(photo) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:mButton];

}

 

- (void)camera {

    //判断是否由摄像头

    BOOL isCamera = [UIImagePickerController isCameraDeviceAvailable:(UIImagePickerControllerCameraDeviceRear)];

    //UIImagePickerControllerCameraDeviceRear后置摄像头

    //前置摄像头UIImagePickerControllerCameraDeviceFront

    if (!isCamera) {

        NSLog(@"没有后置摄像头");

        return;

    }

    

    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;

    imagePicker.delegate = self;

    imagePicker.editing = YES;//相机照的照片是否允许编辑

    [self presentViewController:imagePicker animated:YES completion:^{

    }];

}

 

//调取相册

- (void)photo {

    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    imagePicker.delegate = self;

    [self presentViewController:imagePicker animated:YES completion:nil];

}

 

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {

    //选取相册照片

    imageView.image = image;

    [self dismissViewControllerAnimated:YES completion:nil];

}

 

@end

 

  二、在一的基础上得到的照片要保存本地

  1、保存

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {  

    [[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image) forKey:@"userImage"];

    [self dismissViewControllerAnimated:YES completion:nil];

}

  2、取出

NSData* imageData = [[NSUserDefaults standardUserDefaults] objectForKey:@"userImage"];

UIImage *userImage = [UIImage imageWithData:imageData];

  三、在二中取出的图片是有问题的。

  一幅图片除了包含我们能看见的像素信息,背后还包含了拍摄时间,光圈大小,曝光等信息。UIImage类将这些细节信息都隐藏了起来,只提供我们关心的图片尺寸,图片方向等。用相机拍摄出来的照片含有EXIF信息,UIImage的imageOrientation属性指的就是EXIF中的orientation信息。如果我们忽略orientation信息,而直接对照片进行像素处理或者drawInRect等操作,得到的结果是翻转或者旋转90之后的样子。这是因为我们执行像素处理或者drawInRect等操作之后,imageOrientaion信息被删除了,imageOrientaion被重设为0,造成照片内容和imageOrientaion不匹配。

  目前市面上的大部分数码相机和手机都会内置一个方向感应器,拍出的照片中会写如方向信息,但是通常都只会有前四种方向。这几种Mirrored方向通常都是手机前置摄像头自拍的时候才会设置。

enum {
    exifOrientationUp = 1,      // UIImageOrientationUp
    exifOrientationDown = 3,    // UIImageOrientationDown
    exifOrientationLeft = 6,    // UIImageOrientationLeft
    exifOrientationRight = 8,   // UIImageOrientationRight
    
    // these four exifOrientation does not support by all camera, but IOS support these orientation
    exifOrientationUpMirrored = 2,          // UIImageOrientationUpMirrored
    exifOrientationDownMirrored = 4,        // UIImageOrientationDownMirrored
    exifOrientationLeftMirrored = 5,        // UIImageOrientationLeftMirrored
    exifOrientationRightMirrored = 7,       // UIImageOrientationRightMirrored
};
typedef NSInteger ExifOrientation;

  所以,在对照片进行保存之后,也需要将imageOrientaion这个代表方向的值保存起来,取出的时候再调整图片的方向。废话不多说了,上代码:

  1、保存

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {

    [[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image) forKey:@"userImage"];

    

    [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInteger:image.imageOrientation] forKey:@"userImage_imageOrientation"];

    

    [self dismissViewControllerAnimated:YES completion:nil];

}

  2、取出

NSData* imageData = [[NSUserDefaults standardUserDefaults] objectForKey:@"userImage"];

UIImage *userImage = [UIImage imageWithData:imageData];

NSInteger imageOrientation = [[userDefault objectForKey:@"userImage_imageOrientation"] integerValue];         

imageView.image = [self fixOrientationWithImage:userImage AndImageOrientation:imageOrientation];

//根据保存的方向值选择图片

- (UIImage *)fixOrientationWithImage:(UIImage *)aImage AndImageOrientation:(NSInteger)imageOrientation {

    if (imageOrientation == UIImageOrientationUp)

        return aImage;

    

    CGAffineTransform transform = CGAffineTransformIdentity;

    

    switch (imageOrientation) {

        case UIImageOrientationDown:

        case UIImageOrientationDownMirrored:

            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);

            transform = CGAffineTransformRotate(transform, M_PI);

            break;

        case UIImageOrientationLeft:

        case UIImageOrientationLeftMirrored:

            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);

            transform = CGAffineTransformRotate(transform, M_PI_2);

            break; 

        case UIImageOrientationRight:

        case UIImageOrientationRightMirrored:

            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);

            transform = CGAffineTransformRotate(transform, -M_PI_2);

            break;

        default:

            break;

    }

    

    switch (imageOrientation) {

        case UIImageOrientationUpMirrored:

        case UIImageOrientationDownMirrored:

            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);

            transform = CGAffineTransformScale(transform, -1, 1);

            break;

        case UIImageOrientationLeftMirrored:

        case UIImageOrientationRightMirrored:

            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);

            transform = CGAffineTransformScale(transform, -1, 1);

            break;

        default:

            break;

    }

    

    CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,

                                             CGImageGetBitsPerComponent(aImage.CGImage), 0,

                                             CGImageGetColorSpace(aImage.CGImage),

                                             CGImageGetBitmapInfo(aImage.CGImage));

    CGContextConcatCTM(ctx, transform);

    switch (imageOrientation) {

        case UIImageOrientationLeft:

        case UIImageOrientationLeftMirrored:

        case UIImageOrientationRight:

        case UIImageOrientationRightMirrored:

            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);

            break;

        default:

            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);

            break;

    }

    

    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);

    UIImage *img = [UIImage imageWithCGImage:cgimg];

    CGContextRelease(ctx);

    CGImageRelease(cgimg);

    return img;

}

原文地址:https://www.cnblogs.com/yyt-hehe-yyt/p/5315897.html