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

    }

  • 相关阅读:
    一、Java语言基础(2)_类型和运算——基本数据类型转换
    一、Java语言基础(2)_类型和运算——数据类型和分类
    一、Java语言基础(2)_类型和运算——字面量和常量
    一、Java语言基础(1)_走进java——基本语法
    接口测试彻底弄懂Session、Cookie、Token的区别及联系hold住面试官--hold住了开3万,hold不住开3K!
    待过猫厂、狗厂、鹅厂、猪厂的10年测试码农告诉你-测试计划与测试方案的区别?
    2020非常全的接口测试面试题及参考答案-软件测试工程师没有碰到算我输!
    2020非常全的软件测试linux常用命令全集,linux面试题及参考答案
    jmeter实现接口关联的两种方式:正则表达式提取器和json提取器看这篇就够了
    通过pycharm使用git和github的步骤(图文详解)
  • 原文地址:https://www.cnblogs.com/yyt-hehe-yyt/p/5315897.html
Copyright © 2020-2023  润新知