• 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;

    }

  • 相关阅读:
    dfs和bfs算法
    7种查找算法详解(转)
    C语言关键字:auto、static、register、const、volatile 、extern 总结 <转>
    存储类型auto,static,extern,register的区别 <转>
    C++中的内存重叠问题
    auto和register关键字
    监控linux系统的简易脚本
    Linux下面的IO模型
    python--爬虫基础
    网络协议面试
  • 原文地址:https://www.cnblogs.com/yyt-hehe-yyt/p/5315897.html
Copyright © 2020-2023  润新知